]> git.saurik.com Git - apple/objc4.git/blob - test/rr-autorelease-fast.m
objc4-680.tar.gz
[apple/objc4.git] / test / rr-autorelease-fast.m
1 // TEST_CONFIG CC=clang MEM=mrc
2 // TEST_CFLAGS -Os
3
4 #include "test.h"
5 #include "testroot.i"
6
7 #if __i386__
8
9 int main()
10 {
11 // no optimization on i386 (neither Mac nor Simulator)
12 succeed(__FILE__);
13 }
14
15 #else
16
17 #include <objc/objc-internal.h>
18 #include <objc/objc-abi.h>
19 #include <Foundation/Foundation.h>
20
21 @interface TestObject : TestRoot @end
22 @implementation TestObject @end
23
24
25 #ifdef __arm__
26 # define MAGIC asm volatile("mov r7, r7")
27 # define NOT_MAGIC asm volatile("mov r6, r6")
28 #elif __arm64__
29 # define MAGIC asm volatile("mov x29, x29")
30 # define NOT_MAGIC asm volatile("mov x28, x28")
31 #elif __x86_64__
32 # define MAGIC asm volatile("")
33 # define NOT_MAGIC asm volatile("nop")
34 #else
35 # error unknown architecture
36 #endif
37
38
39 int
40 main()
41 {
42 TestObject *tmp, *obj;
43
44 #ifdef __x86_64__
45 // need to get DYLD to resolve the stubs on x86
46 PUSH_POOL {
47 TestObject *warm_up = [[TestObject alloc] init];
48 testassert(warm_up);
49 warm_up = objc_retainAutoreleasedReturnValue(warm_up);
50 warm_up = objc_unsafeClaimAutoreleasedReturnValue(warm_up);
51 [warm_up release];
52 warm_up = nil;
53 } POP_POOL;
54 #endif
55
56 testprintf(" Successful +1 -> +1 handshake\n");
57
58 PUSH_POOL {
59 obj = [[TestObject alloc] init];
60 testassert(obj);
61
62 TestRootRetain = 0;
63 TestRootRelease = 0;
64 TestRootAutorelease = 0;
65 TestRootDealloc = 0;
66
67 tmp = objc_autoreleaseReturnValue(obj);
68 MAGIC;
69 tmp = objc_retainAutoreleasedReturnValue(tmp);
70
71 testassert(TestRootDealloc == 0);
72 testassert(TestRootRetain == 0);
73 testassert(TestRootRelease == 0);
74 testassert(TestRootAutorelease == 0);
75
76 [tmp release];
77 testassert(TestRootDealloc == 1);
78 testassert(TestRootRetain == 0);
79 testassert(TestRootRelease == 1);
80 testassert(TestRootAutorelease == 0);
81
82 } POP_POOL;
83
84 testprintf("Unsuccessful +1 -> +1 handshake\n");
85
86 PUSH_POOL {
87 obj = [[TestObject alloc] init];
88 testassert(obj);
89
90 TestRootRetain = 0;
91 TestRootRelease = 0;
92 TestRootAutorelease = 0;
93 TestRootDealloc = 0;
94
95 tmp = objc_autoreleaseReturnValue(obj);
96 NOT_MAGIC;
97 tmp = objc_retainAutoreleasedReturnValue(tmp);
98
99 testassert(TestRootDealloc == 0);
100 testassert(TestRootRetain == 1);
101 testassert(TestRootRelease == 0);
102 testassert(TestRootAutorelease == 1);
103
104 [tmp release];
105 testassert(TestRootDealloc == 0);
106 testassert(TestRootRetain == 1);
107 testassert(TestRootRelease == 1);
108 testassert(TestRootAutorelease == 1);
109
110 } POP_POOL;
111 testassert(TestRootDealloc == 1);
112 testassert(TestRootRetain == 1);
113 testassert(TestRootRelease == 2);
114 testassert(TestRootAutorelease == 1);
115
116
117 testprintf(" Successful +0 -> +1 handshake\n");
118
119 PUSH_POOL {
120 obj = [[TestObject alloc] init];
121 testassert(obj);
122
123 TestRootRetain = 0;
124 TestRootRelease = 0;
125 TestRootAutorelease = 0;
126 TestRootDealloc = 0;
127
128 tmp = objc_retainAutoreleaseReturnValue(obj);
129 MAGIC;
130 tmp = objc_retainAutoreleasedReturnValue(tmp);
131
132 testassert(TestRootDealloc == 0);
133 testassert(TestRootRetain == 1);
134 testassert(TestRootRelease == 0);
135 testassert(TestRootAutorelease == 0);
136
137 [tmp release];
138 testassert(TestRootDealloc == 0);
139 testassert(TestRootRetain == 1);
140 testassert(TestRootRelease == 1);
141 testassert(TestRootAutorelease == 0);
142
143 [tmp release];
144 testassert(TestRootDealloc == 1);
145 testassert(TestRootRetain == 1);
146 testassert(TestRootRelease == 2);
147 testassert(TestRootAutorelease == 0);
148
149 } POP_POOL;
150
151 testprintf("Unsuccessful +0 -> +1 handshake\n");
152
153 PUSH_POOL {
154 obj = [[TestObject alloc] init];
155 testassert(obj);
156
157 TestRootRetain = 0;
158 TestRootRelease = 0;
159 TestRootAutorelease = 0;
160 TestRootDealloc = 0;
161
162 tmp = objc_retainAutoreleaseReturnValue(obj);
163 NOT_MAGIC;
164 tmp = objc_retainAutoreleasedReturnValue(tmp);
165
166 testassert(TestRootDealloc == 0);
167 testassert(TestRootRetain == 2);
168 testassert(TestRootRelease == 0);
169 testassert(TestRootAutorelease == 1);
170
171 [tmp release];
172 testassert(TestRootDealloc == 0);
173 testassert(TestRootRetain == 2);
174 testassert(TestRootRelease == 1);
175 testassert(TestRootAutorelease == 1);
176
177 [tmp release];
178 testassert(TestRootDealloc == 0);
179 testassert(TestRootRetain == 2);
180 testassert(TestRootRelease == 2);
181 testassert(TestRootAutorelease == 1);
182
183 } POP_POOL;
184 testassert(TestRootDealloc == 1);
185 testassert(TestRootRetain == 2);
186 testassert(TestRootRelease == 3);
187 testassert(TestRootAutorelease == 1);
188
189
190 testprintf(" Successful +1 -> +0 handshake\n");
191
192 PUSH_POOL {
193 obj = [[[TestObject alloc] init] retain];
194 testassert(obj);
195
196 TestRootRetain = 0;
197 TestRootRelease = 0;
198 TestRootAutorelease = 0;
199 TestRootDealloc = 0;
200
201 tmp = objc_autoreleaseReturnValue(obj);
202 MAGIC;
203 tmp = objc_unsafeClaimAutoreleasedReturnValue(tmp);
204
205 testassert(TestRootDealloc == 0);
206 testassert(TestRootRetain == 0);
207 testassert(TestRootRelease == 1);
208 testassert(TestRootAutorelease == 0);
209
210 [tmp release];
211 testassert(TestRootDealloc == 1);
212 testassert(TestRootRetain == 0);
213 testassert(TestRootRelease == 2);
214 testassert(TestRootAutorelease == 0);
215
216 } POP_POOL;
217
218 testprintf("Unsuccessful +1 -> +0 handshake\n");
219
220 PUSH_POOL {
221 obj = [[[TestObject alloc] init] retain];
222 testassert(obj);
223
224 TestRootRetain = 0;
225 TestRootRelease = 0;
226 TestRootAutorelease = 0;
227 TestRootDealloc = 0;
228
229 tmp = objc_autoreleaseReturnValue(obj);
230 NOT_MAGIC;
231 tmp = objc_unsafeClaimAutoreleasedReturnValue(tmp);
232
233 testassert(TestRootDealloc == 0);
234 testassert(TestRootRetain == 0);
235 testassert(TestRootRelease == 0);
236 testassert(TestRootAutorelease == 1);
237
238 [tmp release];
239 testassert(TestRootDealloc == 0);
240 testassert(TestRootRetain == 0);
241 testassert(TestRootRelease == 1);
242 testassert(TestRootAutorelease == 1);
243
244 } POP_POOL;
245 testassert(TestRootDealloc == 1);
246 testassert(TestRootRetain == 0);
247 testassert(TestRootRelease == 2);
248 testassert(TestRootAutorelease == 1);
249
250
251 testprintf(" Successful +0 -> +0 handshake\n");
252
253 PUSH_POOL {
254 obj = [[TestObject alloc] init];
255 testassert(obj);
256
257 TestRootRetain = 0;
258 TestRootRelease = 0;
259 TestRootAutorelease = 0;
260 TestRootDealloc = 0;
261
262 tmp = objc_retainAutoreleaseReturnValue(obj);
263 MAGIC;
264 tmp = objc_unsafeClaimAutoreleasedReturnValue(tmp);
265
266 testassert(TestRootDealloc == 0);
267 testassert(TestRootRetain == 0);
268 testassert(TestRootRelease == 0);
269 testassert(TestRootAutorelease == 0);
270
271 [tmp release];
272 testassert(TestRootDealloc == 1);
273 testassert(TestRootRetain == 0);
274 testassert(TestRootRelease == 1);
275 testassert(TestRootAutorelease == 0);
276
277 } POP_POOL;
278
279 testprintf("Unsuccessful +0 -> +0 handshake\n");
280
281 PUSH_POOL {
282 obj = [[TestObject alloc] init];
283 testassert(obj);
284
285 TestRootRetain = 0;
286 TestRootRelease = 0;
287 TestRootAutorelease = 0;
288 TestRootDealloc = 0;
289
290 tmp = objc_retainAutoreleaseReturnValue(obj);
291 NOT_MAGIC;
292 tmp = objc_unsafeClaimAutoreleasedReturnValue(tmp);
293
294 testassert(TestRootDealloc == 0);
295 testassert(TestRootRetain == 1);
296 testassert(TestRootRelease == 0);
297 testassert(TestRootAutorelease == 1);
298
299 [tmp release];
300 testassert(TestRootDealloc == 0);
301 testassert(TestRootRetain == 1);
302 testassert(TestRootRelease == 1);
303 testassert(TestRootAutorelease == 1);
304
305 } POP_POOL;
306 testassert(TestRootDealloc == 1);
307 testassert(TestRootRetain == 1);
308 testassert(TestRootRelease == 2);
309 testassert(TestRootAutorelease == 1);
310
311 succeed(__FILE__);
312
313 return 0;
314 }
315
316
317 #endif