ObjFW  Diff

Differences From Artifact [9b9e08d0f0]:

  • File src/OFAutoreleasePool.m — part of check-in [f5927f8a84] at 2012-07-14 20:00:11 on branch trunk — New autorelease pools.

    This uses the runtime's autorelease pools and implements autorelease
    pools in the ObjFW runtime. It therefore uses ObjFW's autorelease pools
    when using the ObjFW runtime and Apple's autorelease pools when using
    the Apple runtime.

    These new pools should be ARC-compatible now and finally, it should be
    possible to mix OFAutoreleasePools and NSAutoreleasePools again, even
    @autoreleasepool is allowed in the mix now. This also means the old
    bridge to NSAutoreleasePool should not be required anymore, as both use
    the runtime's autorelease pools now.

    As a bonus, it's significantly faster to use the ObjFW runtime with
    ObjFW's autorelease pools than to use Apple's runtime with Apple's
    autorelease pools, as a quick benchmark using OFXMLParser on large files
    showed. (Note: This is not only due to the different autorelease pools,
    but also due to the fact that even with the same autorelease pools it is
    faster using the ObjFW runtime, as can be seen in versions prior to this
    commit.) (user: js, size: 1924) [annotate] [blame] [check-ins using]

To Artifact [20bd5ed7f7]:


13
14
15
16
17
18
19


20
21
22






23
24
25
26
27
28
29

30



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
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#include <stdlib.h>



#import "OFAutoreleasePool.h"
#import "OFArray.h"







#import "OFNotImplementedException.h"

extern id _objc_rootAutorelease(id);
extern void* objc_autoreleasePoolPush(void);
extern void objc_autoreleasePoolPop(void*);


static __thread void *first = NULL;




@implementation OFAutoreleasePool












+ (id)addObject: (id)object
{




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

	return _objc_rootAutorelease(object);
}

+ (void)_releaseAll
{




	objc_autoreleasePoolPop(first);
}

- init
{
	self = [super init];

	@try {




		pool = objc_autoreleasePoolPush();

		if (first == NULL)

			first = pool;






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








>
>



>
>
>
>
>
>







>

>
>
>


>
>
>
>
>
>
>
>
>
>
>
>


>
>
>
>








>
>
>
>








>
>
>
>



>

>
>
>
>
>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
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
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#include <stdlib.h>

#include <assert.h>

#import "OFAutoreleasePool.h"
#import "OFArray.h"

#ifndef OF_COMPILER_TLS
# import "threading.h"

# import "OFInitializationFailedException.h"
#endif

#import "OFNotImplementedException.h"

extern id _objc_rootAutorelease(id);
extern void* objc_autoreleasePoolPush(void);
extern void objc_autoreleasePoolPop(void*);

#ifdef OF_COMPILER_TLS
static __thread void *first = NULL;
#else
static of_tlskey_t firstKey;
#endif

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

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

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

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

	return _objc_rootAutorelease(object);
}

+ (void)_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
			if (!of_tlskey_set(firstKey, pool))
				@throw [OFInitializationFailedException
				    exceptionWithClass: [self class]];
#endif

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

87
88
89
90
91
92
93

94
95




96
97
98
99
100
101
102
- (void)dealloc
{
	if (ignoreRelease)
		return;

	ignoreRelease = YES;


	if (first == pool)
		first = NULL;





	objc_autoreleasePoolPop(pool);

	[super dealloc];
}

- retain







>


>
>
>
>







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
- (void)dealloc
{
	if (ignoreRelease)
		return;

	ignoreRelease = YES;

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

	objc_autoreleasePoolPop(pool);

	[super dealloc];
}

- retain