ObjFW  Check-in [c9bea2982f]

Overview
Comment:Simplify autoreleasing.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: c9bea2982f3d1b2ce2b00c65e18caf054fa153f3f3f82614ff82cd54c49262a4
User & Date: js on 2012-09-17 09:30:38
Other Links: manifest | tags
Context
2012-09-17
10:11
OFTimer: Fix -[initWith...block:]. check-in: 1550e4988b user: js tags: trunk
09:30
Simplify autoreleasing. check-in: c9bea2982f user: js tags: trunk
06:59
Only schedule valid timers for repeating. check-in: 6673513f33 user: js tags: trunk
Changes

Modified src/OFApplication.m from [e32044da23] to [5bede79f26].

292
293
294
295
296
297
298
299
300
301
302
303
304


305
306
307
308
309
310
311
	REGISTER_SIGNAL(SIGUSR2)
#endif
#undef REGISTER_SIGNAL
}

- (void)run
{
	void *pool;
	OFRunLoop *runLoop;

	[OFThread OF_createMainThread];
	runLoop = [OFRunLoop currentRunLoop];
	[OFRunLoop OF_setMainRunLoop];



	pool = objc_autoreleasePoolPush();
	[delegate applicationDidFinishLaunching];
	objc_autoreleasePoolPop(pool);

	[runLoop run];
}







|





>
>







292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
	REGISTER_SIGNAL(SIGUSR2)
#endif
#undef REGISTER_SIGNAL
}

- (void)run
{
	void *pool = objc_autoreleasePoolPush();
	OFRunLoop *runLoop;

	[OFThread OF_createMainThread];
	runLoop = [OFRunLoop currentRunLoop];
	[OFRunLoop OF_setMainRunLoop];

	objc_autoreleasePoolPop(pool);

	pool = objc_autoreleasePoolPush();
	[delegate applicationDidFinishLaunching];
	objc_autoreleasePoolPop(pool);

	[runLoop run];
}

Modified src/OFAutoreleasePool.h from [cce576bf12] to [5fa48ae30d].

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
 *	  thread-specific autorelease pool stack.
 *
 * \param object The object to add to the autorelease pool
 * \return The object
 */
+ (id)addObject: (id)object;

+ (void)OF_releaseAll;

/**
 * \brief Releases all objects in the autorelease pool.
 *
 * This does not free the memory allocated to store pointers to the objects in
 * the pool, so reusing the pool does not allocate any memory until the previous
 * number of objects is exceeded. It behaves this way to optimize loops that
 * always work with the same or similar number of objects and call relaseObjects







<
<







35
36
37
38
39
40
41


42
43
44
45
46
47
48
 *	  thread-specific autorelease pool stack.
 *
 * \param object The object to add to the autorelease pool
 * \return The object
 */
+ (id)addObject: (id)object;



/**
 * \brief Releases all objects in the autorelease pool.
 *
 * This does not free the memory allocated to store pointers to the objects in
 * the pool, so reusing the pool does not allocate any memory until the previous
 * number of objects is exceeded. It behaves this way to optimize loops that
 * always work with the same or similar number of objects and call relaseObjects

Modified src/OFAutoreleasePool.m from [f049b285d4] to [b7dda03eca].

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#endif

#import "autorelease.h"

#define MAX_CACHE_SIZE 0x20

#ifdef OF_COMPILER_TLS
static __thread void *first = NULL;
static __thread OFAutoreleasePool **cache = NULL;
#else
static of_tlskey_t firstKey, cacheKey;
#endif

id
of_autorelease(id object)
{
#ifndef OF_COMPILER_TLS
	void *first = of_tlskey_get(firstKey);
#endif

	if (first == NULL)
		[[OFAutoreleasePool alloc] init];

	return _objc_rootAutorelease(object);
}

@implementation OFAutoreleasePool
#ifndef OF_COMPILER_TLS
+ (void)initialize
{
	if (self != [OFAutoreleasePool class])
		return;

	if (!of_tlskey_new(&firstKey) || !of_tlskey_new(&cacheKey))
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
}
#endif

+ alloc
{







<


|

<
<
<
<
<
<
<
<
<
<
<
<
<








|







31
32
33
34
35
36
37

38
39
40
41













42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#endif

#import "autorelease.h"

#define MAX_CACHE_SIZE 0x20

#ifdef OF_COMPILER_TLS

static __thread OFAutoreleasePool **cache = NULL;
#else
static of_tlskey_t cacheKey;
#endif














@implementation OFAutoreleasePool
#ifndef OF_COMPILER_TLS
+ (void)initialize
{
	if (self != [OFAutoreleasePool class])
		return;

	if (!of_tlskey_new(&cacheKey))
		@throw [OFInitializationFailedException
		    exceptionWithClass: self];
}
#endif

+ alloc
{
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
	}

	return [super alloc];
}

+ (id)addObject: (id)object
{
	return of_autorelease(object);
}

+ (void)OF_releaseAll
{
#ifndef OF_COMPILER_TLS
	void *first = of_tlskey_get(firstKey);
#endif

	objc_autoreleasePoolPop(first);
}

- init
{
	self = [super init];

	@try {
#ifndef OF_COMPILER_TLS
		void *first = of_tlskey_get(firstKey);
#endif

		pool = objc_autoreleasePoolPush();

		if (first == NULL)
#ifdef OF_COMPILER_TLS
			first = pool;
#else
			OF_ENSURE(of_tlskey_set(firstKey, pool));
#endif

		_objc_rootAutorelease(self);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;







|
<
<
<
<
<
<
<
<
<







<
<
<
<


<
<
<
<
<
<
<







72
73
74
75
76
77
78
79









80
81
82
83
84
85
86




87
88







89
90
91
92
93
94
95
	}

	return [super alloc];
}

+ (id)addObject: (id)object
{
	return _objc_rootAutorelease(object);









}

- init
{
	self = [super init];

	@try {




		pool = objc_autoreleasePoolPush();








		_objc_rootAutorelease(self);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#endif

	if (ignoreRelease)
		return;

	ignoreRelease = YES;

#ifdef OF_COMPILER_TLS
	if (first == pool)
		first = NULL;
#else
	if (of_tlskey_get(firstKey) == pool)
		OF_ENSURE(of_tlskey_set(firstKey, NULL));
#endif

	objc_autoreleasePoolPop(pool);

	if (cache == NULL) {
		cache = calloc(sizeof(OFAutoreleasePool*), MAX_CACHE_SIZE);

#ifndef OF_COMPILER_TLS
		if (!of_tlskey_set(cacheKey, cache)) {







<
<
<
<
<
<
<
<







124
125
126
127
128
129
130








131
132
133
134
135
136
137
#endif

	if (ignoreRelease)
		return;

	ignoreRelease = YES;









	objc_autoreleasePoolPop(pool);

	if (cache == NULL) {
		cache = calloc(sizeof(OFAutoreleasePool*), MAX_CACHE_SIZE);

#ifndef OF_COMPILER_TLS
		if (!of_tlskey_set(cacheKey, cache)) {

Modified src/OFObject.m from [5b25661283] to [13e68b8637].

939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
	if (--PRE_IVAR->retainCount == 0)
		[self dealloc];
#endif
}

- autorelease
{
	return of_autorelease(self);
}

- self
{
	return self;
}








|







939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
	if (--PRE_IVAR->retainCount == 0)
		[self dealloc];
#endif
}

- autorelease
{
	return _objc_rootAutorelease(self);
}

- self
{
	return self;
}

Modified src/OFThread.m from [e8774af2ab] to [5df0e5d983].

50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66

67
68
69
70


71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89






90

91
92
93
94
95
96
97
#import "OFNotImplementedException.h"
#import "OFOutOfRangeException.h"
#import "OFThreadJoinFailedException.h"
#import "OFThreadStartFailedException.h"
#import "OFThreadStillRunningException.h"

#import "atomic.h"

#import "threading.h"

static OFList *TLSKeys;
static of_tlskey_t threadSelfKey;
static OFThread *mainThread;

static id
call_main(id object)
{
	OFThread *thread = (OFThread*)object;


	if (!of_tlskey_set(threadSelfKey, thread))
		@throw [OFInitializationFailedException
		    exceptionWithClass: [thread class]];



	/*
	 * Nasty workaround for thread implementations which can't return a
	 * value on join.
	 */
#ifdef OF_HAVE_BLOCKS
	if (thread->block != NULL)
		thread->returnValue = [thread->block(thread->object) retain];
	else
		thread->returnValue = [[thread main] retain];
#else
	thread->returnValue = [[thread main] retain];
#endif

	[thread handleTermination];

	thread->running = OF_THREAD_WAITING_FOR_JOIN;

	[OFTLSKey callAllDestructors];






	[OFAutoreleasePool OF_releaseAll];


	[thread release];

	return 0;
}

@implementation OFThread







>










>




>
>









<
|
|
<






>
>
>
>
>
>
|
>







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

84
85

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#import "OFNotImplementedException.h"
#import "OFOutOfRangeException.h"
#import "OFThreadJoinFailedException.h"
#import "OFThreadStartFailedException.h"
#import "OFThreadStillRunningException.h"

#import "atomic.h"
#import "autorelease.h"
#import "threading.h"

static OFList *TLSKeys;
static of_tlskey_t threadSelfKey;
static OFThread *mainThread;

static id
call_main(id object)
{
	OFThread *thread = (OFThread*)object;
	void *pool;

	if (!of_tlskey_set(threadSelfKey, thread))
		@throw [OFInitializationFailedException
		    exceptionWithClass: [thread class]];

	pool = objc_autoreleasePoolPush();

	/*
	 * Nasty workaround for thread implementations which can't return a
	 * value on join.
	 */
#ifdef OF_HAVE_BLOCKS
	if (thread->block != NULL)
		thread->returnValue = [thread->block(thread->object) retain];
	else

#endif
		thread->returnValue = [[thread main] retain];


	[thread handleTermination];

	thread->running = OF_THREAD_WAITING_FOR_JOIN;

	[OFTLSKey callAllDestructors];
#ifdef OF_OBJFW_RUNTIME
	/*
	 * As the values returned by objc_autoreleasePoolPush() in the ObjFW
	 * runtime are not actually pointers, but sequential numbers, 0 means
	 * we pop everything.
	 */
	objc_autoreleasePoolPop(0);
#endif

	[thread release];

	return 0;
}

@implementation OFThread
220
221
222
223
224
225
226






227

228
229
230
231
232
233
234

		[thread handleTermination];

		thread->running = OF_THREAD_WAITING_FOR_JOIN;
	}

	[OFTLSKey callAllDestructors];






	[OFAutoreleasePool OF_releaseAll];


	[thread release];

	of_thread_exit();
}

+ (void)OF_createMainThread







>
>
>
>
>
>
|
>







229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

		[thread handleTermination];

		thread->running = OF_THREAD_WAITING_FOR_JOIN;
	}

	[OFTLSKey callAllDestructors];
#ifdef OF_OBJFW_RUNTIME
	/*
	 * As the values returned by objc_autoreleasePoolPush() in the ObjFW
	 * runtime are not actually pointers, but sequential numbers, 0 means
	 * we pop everything.
	 */
	objc_autoreleasePoolPop(0);
#endif

	[thread release];

	of_thread_exit();
}

+ (void)OF_createMainThread

Modified src/exceptions/OFException.m from [e04692d9ff] to [32b20ebef7].

58
59
60
61
62
63
64
65
66
67
68
69
70

- (OFString*)description
{
	if (description != nil)
		return description;

	description = [[OFString alloc] initWithFormat:
	    @"An exception of class %@ occurred in class %@",
	    object_getClass(self), inClass];

	return description;
}
@end







|





58
59
60
61
62
63
64
65
66
67
68
69
70

- (OFString*)description
{
	if (description != nil)
		return description;

	description = [[OFString alloc] initWithFormat:
	    @"An exception of class %@ occurred in class %@!",
	    object_getClass(self), inClass];

	return description;
}
@end