Skip to content

Commit

Permalink
* NSInvocation does not raise anymore during -init as noone should ra…
Browse files Browse the repository at this point in the history
…ise during init

* NSAutoreleasePool name can now be 48-1 bytes long
added animation.html generator for debugging some tests ("hidden" in test/TAO/forward)
  • Loading branch information
Your Name committed Dec 11, 2024
1 parent 4db6a22 commit dff2733
Show file tree
Hide file tree
Showing 20 changed files with 190 additions and 54 deletions.
2 changes: 1 addition & 1 deletion .mulle/share/env/environment-plugin.sh

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .mulle/share/env/version

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .mulle/share/sde/version/mulle-sde/cmake

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ only and for instance not on `<unistd.h>`.

| Release Version | Release Notes
|-------------------------------------------------------|--------------
| ![Mulle kybernetiK tag](https://img.shields.io/github/tag/mulle-objc/MulleObjC.svg?branch=release) [![Build Status](https://github.com/mulle-objc/MulleObjC/workflows/CI/badge.svg?branch=release)](//github.com/mulle-objc/MulleObjC/actions) | [RELEASENOTES](RELEASENOTES.md) |
| ![Mulle kybernetiK tag](https://img.shields.io/github/tag/mulle-objc/MulleObjC.svg) [![Build Status](https://github.com/mulle-objc/MulleObjC/workflows/CI/badge.svg)](//github.com/mulle-objc/MulleObjC/actions) | [RELEASENOTES](RELEASENOTES.md) |


## API
Expand Down
3 changes: 3 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
## 0.25.0

* NSInvocation does not raise anymore during -init as noone should raise during init
* NSAutoreleasePool name can now be 48-1 bytes long

* added new types `NSUIntegerAtomic` and `NSIntegerAtomic` to facilitate @property code
* experimental and *untested* `MulleProxy` class added
* added NSAutoreleasePool debugging facility to dump contents into CSV format for postprocessing with sqlite or scripts
Expand Down
13 changes: 9 additions & 4 deletions cmake/share/InstallRpath.cmake

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/MulleObjCIntegralType.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include <mulle-c11/mulle-c11-bool.h>
#include <mulle-c11/mulle-c11-integer.h>
#include <mulle-thread/mulle-thread.h>

typedef enum
{
Expand Down
8 changes: 7 additions & 1 deletion src/class/NSAutoreleasePool.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
{
NSAutoreleasePool *_owner;
void *_storage;
char _mulleNameUTF8String[ 32];
char _mulleNameUTF8String[ 48];
}

// MEMO: this is marked as threadsafe, but that's because its assumed
Expand Down Expand Up @@ -265,5 +265,11 @@ void MulleObjCDumpAutoreleasePoolsToFileIndexed( char *filename);
MULLE_OBJC_GLOBAL
void MulleObjCDumpAutoreleasePoolsToFILEWithOptions( FILE *fp, int indexed);

//
// MEMO: like the functions above, you should only use them when you
// are in the debugger and a breakpoint has happened, but for debugging
// you can sometimes get by even in running programs, if threads are
// waiting for each other.
//
MULLE_OBJC_GLOBAL
unsigned long MulleObjCDumpAutoreleasePoolsFrame( void);
27 changes: 22 additions & 5 deletions src/class/NSAutoreleasePool.m
Original file line number Diff line number Diff line change
Expand Up @@ -241,14 +241,18 @@ void mulle_objc_thread_done_poolconfiguration( struct _mulle_objc_universe *un
- (char *) mulleNameUTF8String
{
if( ! _mulleNameUTF8String[ 0])
mulle_snprintf( _mulleNameUTF8String, sizeof( _mulleNameUTF8String), "%p", self);
mulle_snprintf( _mulleNameUTF8String, sizeof( _mulleNameUTF8String),
"<NSAutoreleasePool %p>",
MulleObjCInstanceGetClassNameUTF8String( self),
self);
return( &_mulleNameUTF8String[ 0]);
}


- (void) mulleSetNameUTF8String:(char *) s
{
strncpy( _mulleNameUTF8String, s ? s : "", sizeof( _mulleNameUTF8String) - 1);
_mulleNameUTF8String[ sizeof( _mulleNameUTF8String) - 1] = 0;
}


Expand Down Expand Up @@ -1181,7 +1185,10 @@ static inline void _dump_info_init( struct dump_info *p,
{
if( thread != info->thread.mainthread)
{
mulle__pointermap_set( &p->thread_index_map, thread, (void *) (intptr_t) thread_index, NULL);
mulle__pointermap_set( &p->thread_index_map,
thread,
(void *) (intptr_t) thread_index,
NULL);
++thread_index;
}
}
Expand All @@ -1190,6 +1197,9 @@ static inline void _dump_info_init( struct dump_info *p,

static inline void _dump_info_done( struct dump_info *p)
{
mulle_free( p->thread_name);
mulle_free( p->pool_name);

_mulle__pointermap_done( &p->thread_index_map, NULL);
_mulle__pointermap_done( &p->object_index_map, NULL);
}
Expand All @@ -1204,7 +1214,9 @@ static void _dumpinfo_dump_thread( struct dump_info *info,
struct _mulle_objc_poolconfiguration *config;

info->thread_adr = thread;
info->thread_name = [thread mulleNameUTF8String];

mulle_free( info->thread_name);
info->thread_name = mulle_strdup( [thread mulleNameUTF8String]);
info->thread_index = (int) index;
info->pool_index = 0;

Expand All @@ -1214,7 +1226,8 @@ static void _dumpinfo_dump_thread( struct dump_info *info,

for( pool = config->tail; pool; pool = pool->_owner)
{
info->pool_name = [pool mulleNameUTF8String];
mulle_free( info->pool_name);
info->pool_name = mulle_strdup( [pool mulleNameUTF8String]);
info->pool_adr = pool;

--info->pool_index;
Expand Down Expand Up @@ -1250,7 +1263,11 @@ static void _dumpinfo_dump_thread( struct dump_info *info,
_dump_info_done( &dump_info);
}


//
// Though we do a "lock" its just to block another
// MulleObjCDumpAutoreleasePoolsToFILEWithOptions, dumping other threads
// autoreleasepools is obviously risky.
//
void MulleObjCDumpAutoreleasePoolsToFILEWithOptions( FILE *fp, int options)
{
struct _mulle_objc_universe *universe;
Expand Down
2 changes: 1 addition & 1 deletion src/class/NSInvocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
- (void) setSelector:(SEL) selector;

- (id) target;
- (void) setTarget:target;
- (void) setTarget:(id) target;

- (void) invoke;
- (void) invokeWithTarget:(id) target;
Expand Down
24 changes: 8 additions & 16 deletions src/class/NSInvocation.m
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,9 @@ + (NSInvocation *) invocationWithMethodSignature:(NSMethodSignature *) signature
void *extraBytes;
struct _mulle_objc_infraclass *cls;

// MEMO: do not raise during construction of objects
if( ! signature)
{
__mulle_objc_universe_raise_invalidargument( _mulle_objc_object_get_universe( self),
"signature is nil");
return( nil);
}

// frame_size = [signature frameLength];
// size = mulle_metaabi_sizeof_union( frame_size);
Expand Down Expand Up @@ -231,6 +228,9 @@ + (NSInvocation *) mulleInvocationWithTarget:(id) target

signature = [target methodSignatureForSelector:sel];
invocation = [self invocationWithMethodSignature:signature];
if( ! invocation)
return( nil);

[invocation setTarget:target];
[invocation setSelector:sel];

Expand Down Expand Up @@ -268,13 +268,7 @@ + (NSInvocation *) mulleInvocationWithTarget:(id) target
NSInvocation *invocation;
NSMethodSignature *signature;

signature = [target methodSignatureForSelector:sel];
if( ! signature)
MulleObjCThrowInternalInconsistencyExceptionUTF8String( "method not found on target");
if( [signature numberOfArguments] != 3)
MulleObjCThrowInternalInconsistencyExceptionUTF8String( "method must accept one argument");
if( [signature isVariadic])
MulleObjCThrowInternalInconsistencyExceptionUTF8String( "method must not be variadic");
signature = [target methodSignatureForSelector:sel];

invocation = [self invocationWithMethodSignature:signature];
[invocation setTarget:target];
Expand All @@ -297,11 +291,7 @@ + (NSInvocation *) mulleInvocationWithTarget:(id) target
void *adr;
MulleObjCMethodSignatureTypeInfo *p;
#endif
signature = [target methodSignatureForSelector:sel];
if( ! signature)
MulleObjCThrowInternalInconsistencyExceptionUTF8String( "method %x not found on target", sel);
if( [signature isVariadic])
MulleObjCThrowInternalInconsistencyExceptionUTF8String( "method must not be variadic");
signature = [target methodSignatureForSelector:sel];

invocation = [self invocationWithMethodSignature:signature];
[invocation setTarget:target];
Expand Down Expand Up @@ -780,6 +770,8 @@ - (void) invokeWithTarget:(id) target
MulleObjCThrowInternalInconsistencyExceptionUTF8String( "NSInvocation: selector has not been set yet");
if( ! _methodSignature)
MulleObjCThrowInternalInconsistencyExceptionUTF8String( "NSInvocation: methodSignature has not been set yet");
if( [_methodSignature isVariadic])
MulleObjCThrowInternalInconsistencyExceptionUTF8String( "method must not be variadic");

pType = [_methodSignature _methodMetaABIParameterType];
rType = [_methodSignature _methodMetaABIReturnType];
Expand Down
5 changes: 5 additions & 0 deletions src/class/NSObject.m
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ - (void *) forward:(void *) _param MULLE_OBJC_THREADSAFE_METHOD
}
#endif

// MEMO: can't autorelease ahead of init, because init can return
// nil and release object, or release object and return another
// alloced one. So if -init raises, we leak and can't do much
// about. -raise during -init == BAD
//
obj = [_cls alloc];
obj = mulle_objc_object_call_variable_inline( obj,
(mulle_objc_methodid_t) _cmd,
Expand Down
6 changes: 5 additions & 1 deletion src/class/NSThread.m
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,8 @@ - (id) mulleSetRunLoop:(id) runLoop
id otherRunloop;

assert( ! runLoop || [runLoop mulleIsAccessibleByThread:self]);
assert( ! _mulle_objc_object_is_finalized( (struct _mulle_objc_object *) self));

[runLoop retain];
otherRunloop = __mulle_atomic_pointer_compare_and_swap( &self->_runLoop, runLoop, NULL);
if( otherRunloop)
Expand Down Expand Up @@ -1107,7 +1109,9 @@ - (char *) mulleNameUTF8String

s = _mulle_atomic_pointer_read( &_nameUTF8String);
if( ! s)
s = MulleObjC_asprintf( "%p", self);
s = MulleObjC_asprintf( "<%s %p>",
MulleObjCInstanceGetClassNameUTF8String( self),
self);
return( s);
}

Expand Down
6 changes: 3 additions & 3 deletions src/reflect/_MulleObjC-versioncheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

#if defined( MULLE__OBJC__DEBUG_VERSION)
# ifndef MULLE__OBJC__DEBUG_VERSION_MIN
# define MULLE__OBJC__DEBUG_VERSION_MIN ((0UL << 20) | (21 << 8) | 2)
# define MULLE__OBJC__DEBUG_VERSION_MIN ((0UL << 20) | (21 << 8) | 3)
# endif
# ifndef MULLE__OBJC__DEBUG_VERSION_MAX
# define MULLE__OBJC__DEBUG_VERSION_MAX ((0UL << 20) | (22 << 8) | 0)
Expand All @@ -22,10 +22,10 @@

#if defined( MULLE__OBJC__RUNTIME_VERSION)
# ifndef MULLE__OBJC__RUNTIME_VERSION_MIN
# define MULLE__OBJC__RUNTIME_VERSION_MIN ((0UL << 20) | (24 << 8) | 0)
# define MULLE__OBJC__RUNTIME_VERSION_MIN ((0UL << 20) | (25 << 8) | 0)
# endif
# ifndef MULLE__OBJC__RUNTIME_VERSION_MAX
# define MULLE__OBJC__RUNTIME_VERSION_MAX ((0UL << 20) | (25 << 8) | 0)
# define MULLE__OBJC__RUNTIME_VERSION_MAX ((0UL << 20) | (26 << 8) | 0)
# endif
# if MULLE__OBJC__RUNTIME_VERSION < MULLE__OBJC__RUNTIME_VERSION_MIN
# error "mulle-objc-runtime is too old"
Expand Down
2 changes: 1 addition & 1 deletion test/.mulle/share/env/environment-plugin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ export MULLE_SOURCETREE_SYMLINK='YES'
#
#
#
export MULLE_SDE_INSTALLED_VERSION="3.2.0"
export MULLE_SDE_INSTALLED_VERSION="3.2.2"


2 changes: 1 addition & 1 deletion test/.mulle/share/env/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.3.0
5.3.1
2 changes: 1 addition & 1 deletion test/NSAutoreleasePool/pooldump.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ + (instancetype) objectWithNameUTF8String:(char *) s
- (char *) mulleNameUTF8String
{
if( ! _mulleNameUTF8String[ 0])
mulle_snprintf( _mulleNameUTF8String, sizeof( _mulleNameUTF8String), "%p", self);
mulle_snprintf( _mulleNameUTF8String, sizeof( _mulleNameUTF8String), "<Foo %p>", self);
return( &_mulleNameUTF8String[ 0]);
}

Expand Down
21 changes: 19 additions & 2 deletions test/TAO/forward/TAOStrategyTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,24 @@ static void dump_trace_text( unsigned long nr, char *format, va_list args)
}

mulle_vfprintf( fp, format, args);
mulle_fprintf( fp, "\n");
_mulle_stacktrace( NULL, 2, mulle_stacktrace_linefeed, fp);
fclose( fp);
}


static void dump_trace_stack( unsigned long nr)
{
auto char buf[ 19 + 32 + 4 + 1];
FILE *fp;

mulle_snprintf( buf, sizeof( buf), "NSAutoreleasePools_%06d.trc", nr);
fp = fopen( buf, "w");
if( ! fp)
{
perror( "fopen:");
return;
}

_mulle_stacktrace( NULL, 3, mulle_stacktrace_csv, fp);

fclose( fp);
}
Expand All @@ -55,6 +71,7 @@ static void test_trace( char *format, ...)
nr = MulleObjCDumpAutoreleasePoolsFrame();
va_start( args, format);
dump_trace_text( nr, format, args);
dump_trace_stack( nr);
va_end( args);
}
#endif
Expand Down
Loading

0 comments on commit dff2733

Please sign in to comment.