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