Skip to content

Commit

Permalink
flatlaf-natives-windows: reworked memory allocation error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
DevCharly committed Nov 26, 2022
1 parent c3adadf commit c9b5274
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 97 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include <jawt.h>
#include <jawt_md.h>
#include "FlatWndProc.h"
#include "AllocRoutines.h"
#include "com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc.h"

/**
Expand Down Expand Up @@ -101,31 +100,28 @@ HWND FlatWndProc::install( JNIEnv *env, jobject obj, jobject window ) {

// create HWND map
if( hwndMap == NULL ) {
HWNDMap* newHwndMap = new (FlatLafNoThrow) HWNDMap();
if(newHwndMap == NULL) {
hwndMap = new HWNDMap();
if( hwndMap == NULL )
return 0;
} else if(!newHwndMap->isTableAllocated()) {
FlatLafWin32ProcessHeapFree(newHwndMap);
return 0;
}

hwndMap = newHwndMap;
}

// get window handle
HWND hwnd = getWindowHandle( env, window );
if( hwnd == NULL || hwndMap->get( hwnd ) != NULL )
return 0;

FlatWndProc* fwp = new (FlatLafNoThrow) FlatWndProc();
if(fwp == NULL)
FlatWndProc* fwp = new FlatWndProc();
if( fwp == NULL )
return 0;

if( !hwndMap->put( hwnd, fwp ) ) {
delete fwp;
return 0;

}

env->GetJavaVM( &fwp->jvm );
fwp->obj = env->NewGlobalRef( obj );
fwp->hwnd = hwnd;
if(!hwndMap->put( hwnd, fwp ))
return 0;

// replace window procedure
fwp->defaultWndProc = reinterpret_cast<WNDPROC>(
Expand Down Expand Up @@ -154,7 +150,7 @@ void FlatWndProc::uninstall( JNIEnv *env, jobject obj, HWND hwnd ) {
env->DeleteGlobalRef( fwp->obj );
if( fwp->background != NULL )
::DeleteObject( fwp->background );
FlatLafWin32ProcessHeapFree(fwp);
delete fwp;
}

void FlatWndProc::initIDs( JNIEnv *env, jobject obj ) {
Expand Down Expand Up @@ -312,7 +308,7 @@ LRESULT FlatWndProc::WmDestroy( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lPara
if( background != NULL )
::DeleteObject( background );
hwndMap->remove( hwnd );
FlatLafWin32ProcessHeapFree(this);
delete this;

// call original AWT window procedure because it may fire window closed event in AwtWindow::WmDestroy()
return ::CallWindowProc( defaultWndProc2, hwnd, uMsg, wParam, lParam );
Expand Down
50 changes: 24 additions & 26 deletions flatlaf-natives/flatlaf-natives-windows/src/main/cpp/HWNDMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@
#define _NO_CRT_STDIO_INLINE

#include <stdio.h>
#include <stdint.h>
#include <limits.h>
#include "HWNDMap.h"
#include "AllocRoutines.h"

#define DEFAULT_CAPACITY 20
#define INCREASE_CAPACITY 10
Expand All @@ -46,8 +43,8 @@ class LOCK {

HWNDMap::HWNDMap() {
size = 0;
capacity = DEFAULT_CAPACITY;
table = new (FlatLafNoThrow) Entry[capacity];
capacity = 0;
table = NULL;

::InitializeCriticalSection( &criticalSection );

Expand All @@ -69,13 +66,12 @@ bool HWNDMap::put( HWND key, LPVOID value ) {
if( index >= 0 ) {
// key already in map --> replace
table[index].value = value;
return true;
} else {
// insert new key
if(size == INT_MAX || !ensureCapacity( size + 1 ))
if( !ensureCapacity() )
return false;

// make roor for new entry
// make room for new entry
index = -(index + 1);
for( int i = size - 1; i >= index; i-- )
table[i + 1] = table[i];
Expand All @@ -84,10 +80,10 @@ bool HWNDMap::put( HWND key, LPVOID value ) {
// insert entry
table[index].key = key;
table[index].value = value;
return true;
}

// dump( "put" );
return true;
}

void HWNDMap::remove( HWND key ) {
Expand All @@ -108,6 +104,9 @@ void HWNDMap::remove( HWND key ) {
}

int HWNDMap::binarySearch( HWND key ) {
if( table == NULL )
return -1;

__int64 ikey = reinterpret_cast<__int64>( key );
int low = 0;
int high = size - 1;
Expand All @@ -127,37 +126,36 @@ int HWNDMap::binarySearch( HWND key ) {
return -(low + 1);
}

static constexpr size_t MaxEntryArrayLength = (SIZE_MAX >> 1) / sizeof(Entry);
static_assert(MaxEntryArrayLength > 0, "MaxEntryArrayLength > 0 must be true");
bool HWNDMap::ensureCapacity() {
if( table == NULL ) {
table = new Entry[DEFAULT_CAPACITY];
if( table == NULL )
return false;

static constexpr int MaxEntryArrayIntCapacity =
(MaxEntryArrayLength <= INT_MAX) ? static_cast<int>(MaxEntryArrayLength) : INT_MAX;
static_assert(MaxEntryArrayIntCapacity > 0, "MaxEntryArrayIntCapacity > 0 must be true");
capacity = DEFAULT_CAPACITY;
return true;
}

bool HWNDMap::ensureCapacity( int minCapacity ) {
if(minCapacity <= capacity)
// check capacity
int minCapacity = size + 1;
if( minCapacity <= capacity )
return true;
if(minCapacity > MaxEntryArrayIntCapacity)
return false;

// allocate new table
unsigned newCapacity = static_cast<unsigned>(minCapacity) + INCREASE_CAPACITY;
if(newCapacity > MaxEntryArrayIntCapacity)
newCapacity = MaxEntryArrayIntCapacity;

Entry* newTable = new (FlatLafNoThrow) Entry[newCapacity];
if(newTable == NULL)
int newCapacity = minCapacity + INCREASE_CAPACITY;
Entry* newTable = new Entry[newCapacity];
if( newTable == NULL )
return false;

// copy old table to new table
for( int i = 0; i < capacity; i++ )
newTable[i] = table[i];

// delete old table
FlatLafWin32ProcessHeapFree(table);
delete[] table;

table = newTable;
capacity = static_cast<int>(newCapacity);
capacity = newCapacity;
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,10 @@ class HWNDMap
LPVOID get( HWND key );
bool put( HWND key, LPVOID value );
void remove( HWND key );
bool isTableAllocated() noexcept { return static_cast<bool>(table); }

private:
int binarySearch( HWND key );
bool ensureCapacity( int newCapacity );
bool ensureCapacity();

// void dump( char* msg );
};
22 changes: 22 additions & 0 deletions flatlaf-natives/flatlaf-natives-windows/src/main/cpp/Runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,28 @@ BOOL WINAPI _DllMainCRTStartup( HINSTANCE instance, DWORD reason, LPVOID reserve
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"
int __cdecl printf( const char* format, ... ) {
Expand Down

0 comments on commit c9b5274

Please sign in to comment.