]> git.saurik.com Git - apple/objc4.git/blob - test/consolidatePoolPointers.m
objc4-818.2.tar.gz
[apple/objc4.git] / test / consolidatePoolPointers.m
1 //TEST_CONFIG MEM=mrc ARCH=x86_64,ARM64,ARM64e
2 //TEST_ENV OBJC_DISABLE_AUTORELEASE_COALESCING=NO OBJC_DISABLE_AUTORELEASE_COALESCING_LRU=NO
3
4 #include "test.h"
5 #import <Foundation/NSObject.h>
6 #include <os/feature_private.h>
7
8 @interface Counter: NSObject {
9 @public
10 int retains;
11 int releases;
12 int autoreleases;
13 }
14 @end
15 @implementation Counter
16
17 - (id)retain {
18 retains++;
19 return [super retain];
20 }
21
22 - (oneway void)release {
23 releases++;
24 [super release];
25 }
26
27 - (id)autorelease {
28 autoreleases++;
29 return [super autorelease];
30 }
31
32 - (void)dealloc {
33 testprintf("%p dealloc\n", self);
34 [super dealloc];
35 }
36
37 @end
38
39 // Create a number of objects, autoreleasing each one a number of times in a
40 // round robin fashion. Verify that each object gets sent retain, release, and
41 // autorelease the correct number of times. Verify that the gap between
42 // autoreleasepool pointers is the given number of objects. Note: this will not
43 // work when the pool hits a page boundary, to be sure to stay under that limit.
44 void test(int objCount, int autoreleaseCount, int expectedGap) {
45 testprintf("Testing %d objects, %d autoreleases, expecting gap of %d\n",
46 objCount, autoreleaseCount, expectedGap);
47
48 Counter *objs[objCount];
49 for (int i = 0; i < objCount; i++)
50 objs[i] = [Counter new];
51
52 for (int j = 0; j < autoreleaseCount; j++)
53 for (int i = 0; i < objCount; i++)
54 [objs[i] retain];
55
56 for (int i = 0; i < objCount; i++) {
57 testassertequal(objs[i]->retains, autoreleaseCount);
58 testassertequal(objs[i]->releases, 0);
59 testassertequal(objs[i]->autoreleases, 0);
60 }
61
62 void *outer = objc_autoreleasePoolPush();
63 uintptr_t outerAddr = (uintptr_t)outer;
64 for (int j = 0; j < autoreleaseCount; j++)
65 for (int i = 0; i < objCount; i++)
66 [objs[i] autorelease];
67 for (int i = 0; i < objCount; i++) {
68 testassertequal(objs[i]->retains, autoreleaseCount);
69 testassertequal(objs[i]->releases, 0);
70 testassertequal(objs[i]->autoreleases, autoreleaseCount);
71 }
72
73 void *inner = objc_autoreleasePoolPush();
74 uintptr_t innerAddr = (uintptr_t)inner;
75 testprintf("outer=%p inner=%p\n", outer, inner);
76 // Do one more autorelease in the inner pool to make sure we correctly
77 // handle pool boundaries.
78 for (int i = 0; i < objCount; i++)
79 [[objs[i] retain] autorelease];
80 for (int i = 0; i < objCount; i++) {
81 testassertequal(objs[i]->retains, autoreleaseCount + 1);
82 testassertequal(objs[i]->releases, 0);
83 testassertequal(objs[i]->autoreleases, autoreleaseCount + 1);
84 }
85
86 objc_autoreleasePoolPop(inner);
87 for (int i = 0; i < objCount; i++) {
88 testassertequal(objs[i]->retains, autoreleaseCount + 1);
89 testassertequal(objs[i]->releases, 1);
90 testassertequal(objs[i]->autoreleases, autoreleaseCount + 1);
91 }
92
93 objc_autoreleasePoolPop(outer);
94 for (int i = 0; i < objCount; i++) {
95 testassertequal(objs[i]->retains, autoreleaseCount + 1);
96 testassertequal(objs[i]->releases, autoreleaseCount + 1);
97 testassertequal(objs[i]->autoreleases, autoreleaseCount + 1);
98 }
99
100 intptr_t gap = innerAddr - outerAddr;
101 testprintf("gap=%ld\n", gap);
102 testassertequal(gap, expectedGap * sizeof(id));
103
104 // Destroy our test objects.
105 for (int i = 0; i < objCount; i++)
106 [objs[i] release];
107 }
108
109 int main()
110 {
111 // Push a pool here so test() doesn't see a placeholder.
112 objc_autoreleasePoolPush();
113
114 test(1, 1, 2);
115 test(1, 2, 2);
116 test(1, 10, 2);
117 test(1, 100, 2);
118 test(1, 70000, 3);
119
120 test(2, 1, 3);
121 test(2, 2, 3);
122 test(2, 10, 3);
123 test(2, 100, 3);
124 test(2, 70000, 5);
125
126 test(3, 1, 4);
127 test(3, 2, 4);
128 test(3, 10, 4);
129 test(3, 100, 4);
130 test(3, 70000, 7);
131
132 test(4, 1, 5);
133 test(4, 2, 5);
134 test(4, 10, 5);
135 test(4, 100, 5);
136 test(4, 70000, 9);
137
138 test(5, 1, 6);
139 test(5, 2, 11);
140
141 succeed(__FILE__);
142 }