]>
Commit | Line | Data |
---|---|---|
2bfd4448 | 1 | /* |
b3962a83 | 2 | * Copyright (c) 2004-2007 Apple Inc. All rights reserved. |
2bfd4448 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
2bfd4448 A |
6 | * This file contains Original Code and/or Modifications of Original Code |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. Please obtain a copy of the License at | |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
11 | * file. | |
12 | * | |
13 | * The Original Code and all software distributed under the License are | |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
18 | * Please see the License for the specific language governing rights and | |
19 | * limitations under the License. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
2bfd4448 A |
23 | |
24 | #ifndef _OBJC_AUTO_H_ | |
25 | #define _OBJC_AUTO_H_ | |
26 | ||
cd5f04f5 A |
27 | #pragma GCC system_header |
28 | ||
7af964d1 | 29 | #include <objc/objc.h> |
8972963c | 30 | #include <malloc/malloc.h> |
b3962a83 | 31 | #include <stdint.h> |
7af964d1 A |
32 | #include <stddef.h> |
33 | #include <string.h> | |
34 | #include <Availability.h> | |
b3962a83 | 35 | #include <AvailabilityMacros.h> |
7af964d1 A |
36 | #include <TargetConditionals.h> |
37 | ||
38 | #if !TARGET_OS_WIN32 | |
39 | #include <sys/types.h> | |
40 | #include <libkern/OSAtomic.h> | |
41 | #else | |
42 | # define WINVER 0x0501 // target Windows XP and later | |
43 | # define _WIN32_WINNT 0x0501 // target Windows XP and later | |
44 | # define WIN32_LEAN_AND_MEAN | |
45 | // workaround: windef.h typedefs BOOL as int | |
46 | # define BOOL WINBOOL | |
47 | # include <windows.h> | |
48 | # undef BOOL | |
49 | #endif | |
50 | ||
51 | ||
52 | /* GC is unsupported on some architectures. */ | |
53 | ||
8972963c | 54 | #if TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32 |
7af964d1 A |
55 | # define OBJC_NO_GC 1 |
56 | #endif | |
57 | ||
2bfd4448 | 58 | |
7af964d1 | 59 | /* objc_collect() options */ |
2bfd4448 | 60 | enum { |
b3962a83 A |
61 | // choose one |
62 | OBJC_RATIO_COLLECTION = (0 << 0), // run "ratio" generational collections, then a full | |
63 | OBJC_GENERATIONAL_COLLECTION = (1 << 0), // run fast incremental collection | |
64 | OBJC_FULL_COLLECTION = (2 << 0), // run full collection. | |
65 | OBJC_EXHAUSTIVE_COLLECTION = (3 << 0), // run full collections until memory available stops improving | |
66 | ||
67 | OBJC_COLLECT_IF_NEEDED = (1 << 3), // run collection only if needed (allocation threshold exceeded) | |
68 | OBJC_WAIT_UNTIL_DONE = (1 << 4), // wait (when possible) for collection to end before returning (when collector is running on dedicated thread) | |
2bfd4448 A |
69 | }; |
70 | ||
7af964d1 A |
71 | /* objc_clear_stack() options */ |
72 | enum { | |
73 | OBJC_CLEAR_RESIDENT_STACK = (1 << 0) | |
74 | }; | |
75 | ||
8972963c | 76 | #ifndef OBJC_NO_GC |
7af964d1 | 77 | |
7af964d1 | 78 | |
8972963c | 79 | /* GC declarations */ |
2bfd4448 | 80 | |
8972963c A |
81 | /* Collection utilities */ |
82 | ||
83 | OBJC_EXPORT void objc_collect(unsigned long options) | |
84 | __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); | |
85 | OBJC_EXPORT BOOL objc_collectingEnabled(void) | |
86 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
87 | OBJC_EXPORT malloc_zone_t *objc_collectableZone(void) | |
88 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); | |
2bfd4448 | 89 | |
b3962a83 A |
90 | /* GC configuration */ |
91 | ||
92 | /* Tells collector to wait until specified bytes have been allocated before trying to collect again. */ | |
8972963c A |
93 | OBJC_EXPORT void objc_setCollectionThreshold(size_t threshold) |
94 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
b3962a83 A |
95 | |
96 | /* Tells collector to run a full collection for every ratio generational collections. */ | |
8972963c A |
97 | OBJC_EXPORT void objc_setCollectionRatio(size_t ratio) |
98 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
b3962a83 | 99 | |
8972963c A |
100 | // |
101 | // GC-safe compare-and-swap | |
102 | // | |
b3962a83 | 103 | |
7af964d1 | 104 | /* Atomic update, with write barrier. */ |
8972963c A |
105 | OBJC_EXPORT BOOL objc_atomicCompareAndSwapPtr(id predicate, id replacement, volatile id *objectLocation) |
106 | __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA) OBJC_ARC_UNAVAILABLE; | |
7af964d1 | 107 | /* "Barrier" version also includes memory barrier. */ |
8972963c A |
108 | OBJC_EXPORT BOOL objc_atomicCompareAndSwapPtrBarrier(id predicate, id replacement, volatile id *objectLocation) |
109 | __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA) OBJC_ARC_UNAVAILABLE; | |
b3962a83 A |
110 | |
111 | // atomic update of a global variable | |
8972963c A |
112 | OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(id predicate, id replacement, volatile id *objectLocation) |
113 | __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA) OBJC_ARC_UNAVAILABLE; | |
114 | OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobalBarrier(id predicate, id replacement, volatile id *objectLocation) | |
115 | __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA) OBJC_ARC_UNAVAILABLE; | |
b3962a83 | 116 | // atomic update of an instance variable |
8972963c A |
117 | OBJC_EXPORT BOOL objc_atomicCompareAndSwapInstanceVariable(id predicate, id replacement, volatile id *objectLocation) |
118 | __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA) OBJC_ARC_UNAVAILABLE; | |
119 | OBJC_EXPORT BOOL objc_atomicCompareAndSwapInstanceVariableBarrier(id predicate, id replacement, volatile id *objectLocation) | |
120 | __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA) OBJC_ARC_UNAVAILABLE; | |
7af964d1 | 121 | |
b3962a83 | 122 | |
8972963c A |
123 | // |
124 | // Read and write barriers | |
125 | // | |
2bfd4448 | 126 | |
8972963c A |
127 | OBJC_EXPORT id objc_assign_strongCast(id val, id *dest) |
128 | __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA); | |
129 | OBJC_EXPORT id objc_assign_global(id val, id *dest) | |
130 | __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA); | |
131 | OBJC_EXPORT id objc_assign_threadlocal(id val, id *dest) | |
132 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); | |
133 | OBJC_EXPORT id objc_assign_ivar(id value, id dest, ptrdiff_t offset) | |
134 | __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA); | |
135 | OBJC_EXPORT void *objc_memmove_collectable(void *dst, const void *src, size_t size) | |
136 | __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA); | |
137 | ||
138 | OBJC_EXPORT id objc_read_weak(id *location) | |
139 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
140 | OBJC_EXPORT id objc_assign_weak(id value, id *location) | |
141 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
b3962a83 A |
142 | |
143 | ||
144 | // | |
8972963c A |
145 | // Thread management |
146 | // | |
b3962a83 | 147 | |
8972963c A |
148 | /* Register the calling thread with the garbage collector. */ |
149 | OBJC_EXPORT void objc_registerThreadWithCollector(void) | |
150 | __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); | |
b3962a83 | 151 | |
8972963c A |
152 | /* Unregisters the calling thread with the garbage collector. |
153 | Unregistration also happens automatically at thread exit. */ | |
154 | OBJC_EXPORT void objc_unregisterThreadWithCollector(void) | |
155 | __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); | |
b3962a83 | 156 | |
8972963c A |
157 | /* To be called from code which must only execute on a registered thread. */ |
158 | /* If the calling thread is unregistered then an error message is emitted and the thread is implicitly registered. */ | |
159 | OBJC_EXPORT void objc_assertRegisteredThreadWithCollector(void) | |
160 | __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); | |
161 | ||
162 | /* Erases any stale references in unused parts of the stack. */ | |
163 | OBJC_EXPORT void objc_clear_stack(unsigned long options) | |
164 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
b3962a83 | 165 | |
b3962a83 A |
166 | |
167 | // | |
8972963c A |
168 | // Finalization |
169 | // | |
b3962a83 | 170 | |
8972963c A |
171 | /* Returns true if object has been scheduled for finalization. Can be used to avoid operations that may lead to resurrection, which are fatal. */ |
172 | OBJC_EXPORT BOOL objc_is_finalized(void *ptr) | |
173 | __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA); | |
b3962a83 | 174 | |
8972963c A |
175 | // Deprcated. Tells runtime to issue finalize calls on the main thread only. |
176 | OBJC_EXPORT void objc_finalizeOnMainThread(Class cls) | |
177 | AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED; | |
b3962a83 | 178 | |
7af964d1 | 179 | |
8972963c A |
180 | // |
181 | // Deprecated names. | |
182 | // | |
183 | ||
184 | /* Deprecated. Use objc_collectingEnabled() instead. */ | |
185 | OBJC_EXPORT BOOL objc_collecting_enabled(void) | |
186 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4,__MAC_10_5, __IPHONE_NA,__IPHONE_NA); | |
187 | /* Deprecated. Use objc_setCollectionThreshold() instead. */ | |
188 | OBJC_EXPORT void objc_set_collection_threshold(size_t threshold) | |
189 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4,__MAC_10_5, __IPHONE_NA,__IPHONE_NA); | |
190 | /* Deprecated. Use objc_setCollectionRatio() instead. */ | |
191 | OBJC_EXPORT void objc_set_collection_ratio(size_t ratio) | |
192 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4,__MAC_10_5, __IPHONE_NA,__IPHONE_NA); | |
193 | /* Deprecated. Use objc_startCollectorThread() instead. */ | |
194 | OBJC_EXPORT void objc_start_collector_thread(void) | |
195 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4,__MAC_10_5, __IPHONE_NA,__IPHONE_NA); | |
196 | /* Deprecated. No replacement. Formerly told the collector to run using a dedicated background thread. */ | |
197 | OBJC_EXPORT void objc_startCollectorThread(void) | |
198 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5,__MAC_10_7, __IPHONE_NA,__IPHONE_NA); | |
199 | ||
200 | ||
201 | /* Deprecated. Use class_createInstance() instead. */ | |
202 | OBJC_EXPORT id objc_allocate_object(Class cls, int extra) | |
203 | AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER_BUT_DEPRECATED; | |
204 | ||
205 | ||
206 | /* !defined(OBJC_NO_GC) */ | |
207 | #else | |
208 | /* defined(OBJC_NO_GC) */ | |
7af964d1 | 209 | |
7af964d1 | 210 | |
8972963c | 211 | /* Non-GC declarations */ |
7af964d1 | 212 | |
8972963c | 213 | static OBJC_INLINE void objc_collect(unsigned long options __unused) { } |
7af964d1 | 214 | static OBJC_INLINE BOOL objc_collectingEnabled(void) { return NO; } |
8972963c A |
215 | static OBJC_INLINE void objc_setCollectionThreshold(size_t threshold __unused) { } |
216 | static OBJC_INLINE void objc_setCollectionRatio(size_t ratio __unused) { } | |
7af964d1 A |
217 | static OBJC_INLINE void objc_startCollectorThread(void) { } |
218 | ||
cd5f04f5 A |
219 | #if __has_feature(objc_arr) |
220 | ||
221 | /* Covers for GC memory operations are unavailable in ARC */ | |
222 | ||
223 | #else | |
224 | ||
7af964d1 A |
225 | #if TARGET_OS_WIN32 |
226 | static OBJC_INLINE BOOL objc_atomicCompareAndSwapPtr(id predicate, id replacement, volatile id *objectLocation) | |
227 | { void *original = InterlockedCompareExchangePointer((void * volatile *)objectLocation, (void *)replacement, (void *)predicate); return (original == predicate); } | |
228 | ||
229 | static OBJC_INLINE BOOL objc_atomicCompareAndSwapPtrBarrier(id predicate, id replacement, volatile id *objectLocation) | |
230 | { void *original = InterlockedCompareExchangePointer((void * volatile *)objectLocation, (void *)replacement, (void *)predicate); return (original == predicate); } | |
231 | #else | |
232 | static OBJC_INLINE BOOL objc_atomicCompareAndSwapPtr(id predicate, id replacement, volatile id *objectLocation) | |
233 | { return OSAtomicCompareAndSwapPtr((void *)predicate, (void *)replacement, (void * volatile *)objectLocation); } | |
234 | ||
235 | static OBJC_INLINE BOOL objc_atomicCompareAndSwapPtrBarrier(id predicate, id replacement, volatile id *objectLocation) | |
236 | { return OSAtomicCompareAndSwapPtrBarrier((void *)predicate, (void *)replacement, (void * volatile *)objectLocation); } | |
237 | #endif | |
238 | ||
239 | static OBJC_INLINE BOOL objc_atomicCompareAndSwapGlobal(id predicate, id replacement, volatile id *objectLocation) | |
240 | { return objc_atomicCompareAndSwapPtr(predicate, replacement, objectLocation); } | |
241 | ||
242 | static OBJC_INLINE BOOL objc_atomicCompareAndSwapGlobalBarrier(id predicate, id replacement, volatile id *objectLocation) | |
243 | { return objc_atomicCompareAndSwapPtrBarrier(predicate, replacement, objectLocation); } | |
244 | ||
245 | static OBJC_INLINE BOOL objc_atomicCompareAndSwapInstanceVariable(id predicate, id replacement, volatile id *objectLocation) | |
246 | { return objc_atomicCompareAndSwapPtr(predicate, replacement, objectLocation); } | |
247 | ||
248 | static OBJC_INLINE BOOL objc_atomicCompareAndSwapInstanceVariableBarrier(id predicate, id replacement, volatile id *objectLocation) | |
249 | { return objc_atomicCompareAndSwapPtrBarrier(predicate, replacement, objectLocation); } | |
b3962a83 | 250 | |
2bfd4448 | 251 | |
7af964d1 A |
252 | static OBJC_INLINE id objc_assign_strongCast(id val, id *dest) |
253 | { return (*dest = val); } | |
254 | ||
255 | static OBJC_INLINE id objc_assign_global(id val, id *dest) | |
256 | { return (*dest = val); } | |
257 | ||
258 | static OBJC_INLINE id objc_assign_ivar(id val, id dest, ptrdiff_t offset) | |
259 | { return (*(id*)((char *)dest+offset) = val); } | |
260 | ||
7af964d1 A |
261 | static OBJC_INLINE id objc_read_weak(id *location) |
262 | { return *location; } | |
263 | ||
264 | static OBJC_INLINE id objc_assign_weak(id value, id *location) | |
265 | { return (*location = value); } | |
266 | ||
cd5f04f5 A |
267 | /* MRC */ |
268 | #endif | |
269 | ||
270 | static OBJC_INLINE void *objc_memmove_collectable(void *dst, const void *src, size_t size) | |
271 | { return memmove(dst, src, size); } | |
272 | ||
8972963c A |
273 | static OBJC_INLINE void objc_finalizeOnMainThread(Class cls __unused) { } |
274 | static OBJC_INLINE BOOL objc_is_finalized(void *ptr __unused) { return NO; } | |
275 | static OBJC_INLINE void objc_clear_stack(unsigned long options __unused) { } | |
7af964d1 A |
276 | |
277 | static OBJC_INLINE BOOL objc_collecting_enabled(void) { return NO; } | |
8972963c A |
278 | static OBJC_INLINE void objc_set_collection_threshold(size_t threshold __unused) { } |
279 | static OBJC_INLINE void objc_set_collection_ratio(size_t ratio __unused) { } | |
7af964d1 A |
280 | static OBJC_INLINE void objc_start_collector_thread(void) { } |
281 | ||
cd5f04f5 A |
282 | #if __has_feature(objc_arc) |
283 | extern id objc_allocate_object(Class cls, int extra) UNAVAILABLE_ATTRIBUTE; | |
284 | #else | |
8972963c A |
285 | OBJC_EXPORT id class_createInstance(Class cls, size_t extraBytes) |
286 | __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0); | |
7af964d1 A |
287 | static OBJC_INLINE id objc_allocate_object(Class cls, int extra) |
288 | { return class_createInstance(cls, extra); } | |
cd5f04f5 | 289 | #endif |
7af964d1 A |
290 | |
291 | static OBJC_INLINE void objc_registerThreadWithCollector() { } | |
292 | static OBJC_INLINE void objc_unregisterThreadWithCollector() { } | |
293 | static OBJC_INLINE void objc_assertRegisteredThreadWithCollector() { } | |
294 | ||
8972963c | 295 | /* defined(OBJC_NO_GC) */ |
7af964d1 | 296 | #endif |
8972963c A |
297 | |
298 | ||
299 | #if TARGET_OS_EMBEDDED | |
300 | enum { | |
301 | OBJC_GENERATIONAL = (1 << 0) | |
302 | }; | |
303 | static OBJC_INLINE void objc_collect_if_needed(unsigned long options) __attribute__((deprecated)); | |
304 | static OBJC_INLINE void objc_collect_if_needed(unsigned long options __unused) { } | |
305 | #endif | |
306 | ||
2bfd4448 | 307 | #endif |