]> git.saurik.com Git - apple/objc4.git/blob - test/bigrc.m
objc4-781.tar.gz
[apple/objc4.git] / test / bigrc.m
1 // TEST_CONFIG MEM=mrc
2 /*
3 TEST_RUN_OUTPUT
4 objc\[\d+\]: Deallocator object 0x[0-9a-fA-F]+ overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
5 OK: bigrc.m
6 OR
7 no overrelease enforcement
8 OK: bigrc.m
9 END
10 */
11
12 #include "test.h"
13 #include "testroot.i"
14
15 static size_t LOTS;
16
17 @interface Deallocator : TestRoot @end
18 @implementation Deallocator
19
20 -(void)dealloc
21 {
22 id o = self;
23 size_t rc = 1;
24
25
26 testprintf("Retain a lot during dealloc\n");
27
28 testassert(rc == 1);
29 testassert([o retainCount] == rc);
30 do {
31 [o retain];
32 if (rc % 0x100000 == 0) testprintf("%zx/%zx ++\n", rc, LOTS);
33 } while (++rc < LOTS);
34
35 testassert([o retainCount] == rc);
36
37 do {
38 [o release];
39 if (rc % 0x100000 == 0) testprintf("%zx/%zx --\n", rc, LOTS);
40 } while (--rc > 1);
41
42 testassert(rc == 1);
43 testassert([o retainCount] == rc);
44
45
46 testprintf("Overrelease during dealloc\n");
47
48 // Not all architectures enforce this.
49 #if !SUPPORT_NONPOINTER_ISA
50 testwarn("no overrelease enforcement");
51 fprintf(stderr, "no overrelease enforcement\n");
52 #endif
53 [o release];
54
55 [super dealloc];
56 }
57
58 @end
59
60 size_t clz(uintptr_t isa) {
61 if (sizeof(uintptr_t) == 4)
62 return __builtin_clzl(isa);
63 testassert(sizeof(uintptr_t) == 8);
64 return __builtin_clzll(isa);
65 }
66
67 int main()
68 {
69 Deallocator *o = [Deallocator new];
70 size_t rc = 1;
71
72 [o retain];
73
74 uintptr_t isa = *(uintptr_t *)o;
75 if (isa & 1) {
76 // Assume refcount in high bits.
77 LOTS = 1 << (4 + clz(isa));
78 testprintf("LOTS %zu via cntlzw\n", LOTS);
79 } else {
80 LOTS = 0x1000000;
81 testprintf("LOTS %zu via guess\n", LOTS);
82 }
83
84 [o release];
85
86
87 testprintf("Retain a lot\n");
88
89 testassert(rc == 1);
90 testassert([o retainCount] == rc);
91 do {
92 [o retain];
93 if (rc % 0x100000 == 0) testprintf("%zx/%zx ++\n", rc, LOTS);
94 } while (++rc < LOTS);
95
96 testassert([o retainCount] == rc);
97
98 do {
99 [o release];
100 if (rc % 0x100000 == 0) testprintf("%zx/%zx --\n", rc, LOTS);
101 } while (--rc > 1);
102
103 testassert(rc == 1);
104 testassert([o retainCount] == rc);
105
106
107 testprintf("tryRetain a lot\n");
108
109 id w;
110 objc_storeWeak(&w, o);
111 testassert(w == o);
112
113 testassert(rc == 1);
114 testassert([o retainCount] == rc);
115 do {
116 objc_loadWeakRetained(&w);
117 if (rc % 0x100000 == 0) testprintf("%zx/%zx ++\n", rc, LOTS);
118 } while (++rc < LOTS);
119
120 testassert([o retainCount] == rc);
121
122 do {
123 [o release];
124 if (rc % 0x100000 == 0) testprintf("%zx/%zx --\n", rc, LOTS);
125 } while (--rc > 1);
126
127 testassert(rc == 1);
128 testassert([o retainCount] == rc);
129
130 testprintf("dealloc\n");
131
132 testassert(TestRootDealloc == 0);
133 testassert(w != nil);
134 [o release];
135 testassert(TestRootDealloc == 1);
136 testassert(w == nil);
137
138 succeed(__FILE__);
139 }