]> git.saurik.com Git - apple/objc4.git/blob - runtime/objc-private.h
objc4-532.2.tar.gz
[apple/objc4.git] / runtime / objc-private.h
1 /*
2 * Copyright (c) 1999-2007 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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 */
23 /*
24 * objc-private.h
25 * Copyright 1988-1996, NeXT Software, Inc.
26 */
27
28 #ifndef _OBJC_PRIVATE_H_
29 #define _OBJC_PRIVATE_H_
30
31 #include "objc-os.h"
32
33 #include "objc.h"
34 #include "runtime.h"
35 #include "maptable.h"
36 #include "hashtable2.h"
37 #include "objc-api.h"
38 #include "objc-config.h"
39 #include "objc-references.h"
40 #include "objc-initialize.h"
41 #include "objc-loadmethod.h"
42 #include "objc-internal.h"
43 #include "objc-abi.h"
44
45 #include "objc-auto.h"
46
47 #define __APPLE_API_PRIVATE
48 #include "objc-gdb.h"
49 #undef __APPLE_API_PRIVATE
50
51 /* Do not include message.h here. */
52 /* #include "message.h" */
53
54
55 __BEGIN_DECLS
56
57 #ifdef __LP64__
58 # define WORD_SHIFT 3UL
59 # define WORD_MASK 7UL
60 #else
61 # define WORD_SHIFT 2UL
62 # define WORD_MASK 3UL
63 #endif
64
65 #if (defined(OBJC_NO_GC) && SUPPORT_GC) || \
66 (!defined(OBJC_NO_GC) && !SUPPORT_GC)
67 # error OBJC_NO_GC and SUPPORT_GC inconsistent
68 #endif
69
70 #if SUPPORT_GC
71 # include <auto_zone.h>
72 // PRIVATE_EXTERN is needed to help the compiler know "how" extern these are
73 PRIVATE_EXTERN extern BOOL UseGC; // equivalent to calling objc_collecting_enabled()
74 PRIVATE_EXTERN extern BOOL UseCompaction; // if binary has opted-in for compaction.
75 PRIVATE_EXTERN extern auto_zone_t *gc_zone; // the GC zone, or NULL if no GC
76 extern void objc_addRegisteredClass(Class c);
77 extern void objc_removeRegisteredClass(Class c);
78 extern void objc_disableCompaction();
79 #else
80 # define UseGC NO
81 # define UseCompaction NO
82 # define gc_zone NULL
83 # define objc_addRegisteredClass(c) do {} while(0)
84 # define objc_removeRegisteredClass(c) do {} while(0)
85 /* Uses of the following must be protected with UseGC. */
86 extern id gc_unsupported_dont_call();
87 # define auto_zone_allocate_object gc_unsupported_dont_call
88 # define auto_zone_retain gc_unsupported_dont_call
89 # define auto_zone_release gc_unsupported_dont_call
90 # define auto_zone_is_valid_pointer gc_unsupported_dont_call
91 # define auto_zone_write_barrier_memmove gc_unsupported_dont_call
92 # define AUTO_OBJECT_SCANNED 0
93 #endif
94
95 #if __OBJC2__
96 typedef struct objc_cache *Cache;
97 #else
98 // definition in runtime.h
99 #endif
100
101
102 typedef struct {
103 uint32_t version; // currently 0
104 uint32_t flags;
105 } objc_image_info;
106
107 // masks for objc_image_info.flags
108 #define OBJC_IMAGE_IS_REPLACEMENT (1<<0)
109 #define OBJC_IMAGE_SUPPORTS_GC (1<<1)
110 #define OBJC_IMAGE_REQUIRES_GC (1<<2)
111 #define OBJC_IMAGE_OPTIMIZED_BY_DYLD (1<<3)
112 #define OBJC_IMAGE_SUPPORTS_COMPACTION (1<<4)
113
114
115 #define _objcHeaderIsReplacement(h) ((h)->info && ((h)->info->flags & OBJC_IMAGE_IS_REPLACEMENT))
116
117 /* OBJC_IMAGE_IS_REPLACEMENT:
118 Don't load any classes
119 Don't load any categories
120 Do fix up selector refs (@selector points to them)
121 Do fix up class refs (@class and objc_msgSend points to them)
122 Do fix up protocols (@protocol points to them)
123 Do fix up super_class pointers in classes ([super ...] points to them)
124 Future: do load new classes?
125 Future: do load new categories?
126 Future: do insert new methods on existing classes?
127 Future: do insert new methods on existing categories?
128 */
129
130 #define _objcInfoSupportsGC(info) (((info)->flags & OBJC_IMAGE_SUPPORTS_GC) ? 1 : 0)
131 #define _objcInfoRequiresGC(info) (((info)->flags & OBJC_IMAGE_REQUIRES_GC) ? 1 : 0)
132 #define _objcInfoSupportsCompaction(info) (((info)->flags & OBJC_IMAGE_SUPPORTS_COMPACTION) ? 1 : 0)
133 #define _objcHeaderSupportsGC(h) ((h)->info && _objcInfoSupportsGC((h)->info))
134 #define _objcHeaderRequiresGC(h) ((h)->info && _objcInfoRequiresGC((h)->info))
135 #define _objcHeaderSupportsCompaction(h) ((h)->info && _objcInfoSupportsCompaction((h)->info))
136
137 /* OBJC_IMAGE_SUPPORTS_GC:
138 was compiled with -fobjc-gc flag, regardless of whether write-barriers were issued
139 if executable image compiled this way, then all subsequent libraries etc. must also be this way
140 */
141
142 #define _objcHeaderOptimizedByDyld(h) ((h)->info && ((h)->info->flags & OBJC_IMAGE_OPTIMIZED_BY_DYLD))
143
144 /* OBJC_IMAGE_OPTIMIZED_BY_DYLD:
145 Assorted metadata precooked in the dyld shared cache.
146 Never set for images outside the shared cache file itself.
147 */
148
149
150 typedef struct _header_info {
151 struct _header_info *next;
152 const headerType *mhdr;
153 const objc_image_info *info;
154 const char *fname; // same as Dl_info.dli_fname
155 bool loaded;
156 bool inSharedCache;
157 bool allClassesRealized;
158
159 // Do not add fields without editing ObjCModernAbstraction.hpp
160
161 #if !__OBJC2__
162 struct old_protocol **proto_refs;
163 struct objc_module *mod_ptr;
164 size_t mod_count;
165 # if TARGET_OS_WIN32
166 struct objc_module **modules;
167 size_t moduleCount;
168 struct old_protocol **protocols;
169 size_t protocolCount;
170 void *imageinfo;
171 size_t imageinfoBytes;
172 SEL *selrefs;
173 size_t selrefCount;
174 struct objc_class **clsrefs;
175 size_t clsrefCount;
176 TCHAR *moduleName;
177 # endif
178 #endif
179 } header_info;
180
181 extern header_info *FirstHeader;
182 extern header_info *LastHeader;
183 extern int HeaderCount;
184
185 extern void appendHeader(header_info *hi);
186 extern void removeHeader(header_info *hi);
187
188 extern objc_image_info *_getObjcImageInfo(const headerType *head, size_t *size);
189 extern BOOL _hasObjcContents(const header_info *hi);
190
191
192 /* selectors */
193 extern void sel_init(BOOL gc, size_t selrefCount);
194 extern SEL sel_registerNameNoLock(const char *str, BOOL copy);
195 extern void sel_lock(void);
196 extern void sel_unlock(void);
197 extern BOOL sel_preoptimizationValid(const header_info *hi);
198
199 extern SEL SEL_load;
200 extern SEL SEL_initialize;
201 extern SEL SEL_resolveClassMethod;
202 extern SEL SEL_resolveInstanceMethod;
203 extern SEL SEL_cxx_construct;
204 extern SEL SEL_cxx_destruct;
205 extern SEL SEL_retain;
206 extern SEL SEL_release;
207 extern SEL SEL_autorelease;
208 extern SEL SEL_retainCount;
209 extern SEL SEL_alloc;
210 extern SEL SEL_allocWithZone;
211 extern SEL SEL_copy;
212 extern SEL SEL_new;
213 extern SEL SEL_finalize;
214 extern SEL SEL_forwardInvocation;
215
216 /* preoptimization */
217 extern void preopt_init(void);
218 extern void disableSharedCacheOptimizations(void);
219 extern bool isPreoptimized(void);
220 extern header_info *preoptimizedHinfoForHeader(const headerType *mhdr);
221
222 #if __cplusplus
223 namespace objc_opt { struct objc_selopt_t; };
224 extern const struct objc_opt::objc_selopt_t *preoptimizedSelectors(void);
225 extern struct class_t * getPreoptimizedClass(const char *name);
226 #endif
227
228
229
230 /* optional malloc zone for runtime data */
231 extern malloc_zone_t *_objc_internal_zone(void);
232 extern void *_malloc_internal(size_t size);
233 extern void *_calloc_internal(size_t count, size_t size);
234 extern void *_realloc_internal(void *ptr, size_t size);
235 extern char *_strdup_internal(const char *str);
236 extern char *_strdupcat_internal(const char *s1, const char *s2);
237 extern uint8_t *_ustrdup_internal(const uint8_t *str);
238 extern void *_memdup_internal(const void *mem, size_t size);
239 extern void _free_internal(void *ptr);
240 extern size_t _malloc_size_internal(void *ptr);
241
242 extern Class _calloc_class(size_t size);
243
244 extern IMP lookUpMethod(Class, SEL, BOOL initialize, BOOL cache, id obj);
245 extern void lockForMethodLookup(void);
246 extern void unlockForMethodLookup(void);
247 extern IMP prepareForMethodLookup(Class cls, SEL sel, BOOL initialize, id obj);
248
249 extern IMP _cache_getImp(Class cls, SEL sel);
250 extern Method _cache_getMethod(Class cls, SEL sel, IMP objc_msgForward_internal_imp);
251
252 /* message dispatcher */
253 extern IMP _class_lookupMethodAndLoadCache3(id, SEL, Class);
254
255 #if !OBJC_OLD_DISPATCH_PROTOTYPES
256 extern void _objc_msgForward_internal(void);
257 extern void _objc_ignored_method(void);
258 #else
259 extern id _objc_msgForward_internal(id, SEL, ...);
260 extern id _objc_ignored_method(id, SEL, ...);
261 #endif
262
263 /* errors */
264 extern void __objc_error(id, const char *, ...) __attribute__((format (printf, 2, 3), noreturn));
265 extern void _objc_inform(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
266 extern void _objc_inform_on_crash(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
267 extern void _objc_inform_now_and_on_crash(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
268 extern void _objc_inform_deprecated(const char *oldname, const char *newname) __attribute__((noinline));
269 extern void inform_duplicate(const char *name, Class oldCls, Class cls);
270 extern bool crashlog_header_name(header_info *hi);
271 extern bool crashlog_header_name_string(const char *name);
272
273 /* magic */
274 extern Class _objc_getFreedObjectClass (void);
275
276 /* map table additions */
277 extern void *NXMapKeyCopyingInsert(NXMapTable *table, const void *key, const void *value);
278 extern void *NXMapKeyFreeingRemove(NXMapTable *table, const void *key);
279
280 /* hash table additions */
281 extern unsigned _NXHashCapacity(NXHashTable *table);
282 extern void _NXHashRehashToCapacity(NXHashTable *table, unsigned newCapacity);
283
284 /* property attribute parsing */
285 extern const char *copyPropertyAttributeString(const objc_property_attribute_t *attrs, unsigned int count);
286 extern objc_property_attribute_t *copyPropertyAttributeList(const char *attrs, unsigned int *outCount);
287 extern char *copyPropertyAttributeValue(const char *attrs, const char *name);
288
289
290 /* locking */
291 /* Every lock used anywhere must be declared here.
292 * Locks not declared here may cause gdb deadlocks. */
293 extern void lock_init(void);
294 extern rwlock_t selLock;
295 extern mutex_t cacheUpdateLock;
296 extern recursive_mutex_t loadMethodLock;
297 #if __OBJC2__
298 extern rwlock_t runtimeLock;
299 #else
300 extern mutex_t classLock;
301 extern mutex_t methodListLock;
302 #endif
303
304 /* Debugger mode for gdb */
305 #define DEBUGGER_OFF 0
306 #define DEBUGGER_PARTIAL 1
307 #define DEBUGGER_FULL 2
308 extern int startDebuggerMode(void);
309 extern void endDebuggerMode(void);
310
311 #if defined(NDEBUG) || TARGET_OS_WIN32
312
313 #define mutex_lock(m) _mutex_lock_nodebug(m)
314 #define mutex_try_lock(m) _mutex_try_lock_nodebug(m)
315 #define mutex_unlock(m) _mutex_unlock_nodebug(m)
316 #define mutex_assert_locked(m) do { } while (0)
317 #define mutex_assert_unlocked(m) do { } while (0)
318
319 #define recursive_mutex_lock(m) _recursive_mutex_lock_nodebug(m)
320 #define recursive_mutex_try_lock(m) _recursive_mutex_try_lock_nodebug(m)
321 #define recursive_mutex_unlock(m) _recursive_mutex_unlock_nodebug(m)
322 #define recursive_mutex_assert_locked(m) do { } while (0)
323 #define recursive_mutex_assert_unlocked(m) do { } while (0)
324
325 #define monitor_enter(m) _monitor_enter_nodebug(m)
326 #define monitor_exit(m) _monitor_exit_nodebug(m)
327 #define monitor_wait(m) _monitor_wait_nodebug(m)
328 #define monitor_assert_locked(m) do { } while (0)
329 #define monitor_assert_unlocked(m) do { } while (0)
330
331 #define rwlock_read(m) _rwlock_read_nodebug(m)
332 #define rwlock_write(m) _rwlock_write_nodebug(m)
333 #define rwlock_try_read(m) _rwlock_try_read_nodebug(m)
334 #define rwlock_try_write(m) _rwlock_try_write_nodebug(m)
335 #define rwlock_unlock_read(m) _rwlock_unlock_read_nodebug(m)
336 #define rwlock_unlock_write(m) _rwlock_unlock_write_nodebug(m)
337 #define rwlock_assert_reading(m) do { } while (0)
338 #define rwlock_assert_writing(m) do { } while (0)
339 #define rwlock_assert_locked(m) do { } while (0)
340 #define rwlock_assert_unlocked(m) do { } while (0)
341
342 #else
343
344 extern int _mutex_lock_debug(mutex_t *lock, const char *name);
345 extern int _mutex_try_lock_debug(mutex_t *lock, const char *name);
346 extern int _mutex_unlock_debug(mutex_t *lock, const char *name);
347 extern void _mutex_assert_locked_debug(mutex_t *lock, const char *name);
348 extern void _mutex_assert_unlocked_debug(mutex_t *lock, const char *name);
349
350 extern int _recursive_mutex_lock_debug(recursive_mutex_t *lock, const char *name);
351 extern int _recursive_mutex_try_lock_debug(recursive_mutex_t *lock, const char *name);
352 extern int _recursive_mutex_unlock_debug(recursive_mutex_t *lock, const char *name);
353 extern void _recursive_mutex_assert_locked_debug(recursive_mutex_t *lock, const char *name);
354 extern void _recursive_mutex_assert_unlocked_debug(recursive_mutex_t *lock, const char *name);
355
356 extern int _monitor_enter_debug(monitor_t *lock, const char *name);
357 extern int _monitor_exit_debug(monitor_t *lock, const char *name);
358 extern int _monitor_wait_debug(monitor_t *lock, const char *name);
359 extern void _monitor_assert_locked_debug(monitor_t *lock, const char *name);
360 extern void _monitor_assert_unlocked_debug(monitor_t *lock, const char *name);
361
362 extern void _rwlock_read_debug(rwlock_t *l, const char *name);
363 extern void _rwlock_write_debug(rwlock_t *l, const char *name);
364 extern int _rwlock_try_read_debug(rwlock_t *l, const char *name);
365 extern int _rwlock_try_write_debug(rwlock_t *l, const char *name);
366 extern void _rwlock_unlock_read_debug(rwlock_t *l, const char *name);
367 extern void _rwlock_unlock_write_debug(rwlock_t *l, const char *name);
368 extern void _rwlock_assert_reading_debug(rwlock_t *l, const char *name);
369 extern void _rwlock_assert_writing_debug(rwlock_t *l, const char *name);
370 extern void _rwlock_assert_locked_debug(rwlock_t *l, const char *name);
371 extern void _rwlock_assert_unlocked_debug(rwlock_t *l, const char *name);
372
373 #define mutex_lock(m) _mutex_lock_debug (m, #m)
374 #define mutex_try_lock(m) _mutex_try_lock_debug (m, #m)
375 #define mutex_unlock(m) _mutex_unlock_debug (m, #m)
376 #define mutex_assert_locked(m) _mutex_assert_locked_debug (m, #m)
377 #define mutex_assert_unlocked(m) _mutex_assert_unlocked_debug (m, #m)
378
379 #define recursive_mutex_lock(m) _recursive_mutex_lock_debug (m, #m)
380 #define recursive_mutex_try_lock(m) _recursive_mutex_try_lock_debug (m, #m)
381 #define recursive_mutex_unlock(m) _recursive_mutex_unlock_debug (m, #m)
382 #define recursive_mutex_assert_locked(m) _recursive_mutex_assert_locked_debug (m, #m)
383 #define recursive_mutex_assert_unlocked(m) _recursive_mutex_assert_unlocked_debug (m, #m)
384
385 #define monitor_enter(m) _monitor_enter_debug(m, #m)
386 #define monitor_exit(m) _monitor_exit_debug(m, #m)
387 #define monitor_wait(m) _monitor_wait_debug(m, #m)
388 #define monitor_assert_locked(m) _monitor_assert_locked_debug(m, #m)
389 #define monitor_assert_unlocked(m) _monitor_assert_unlocked_debug(m, #m)
390
391 #define rwlock_read(m) _rwlock_read_debug(m, #m)
392 #define rwlock_write(m) _rwlock_write_debug(m, #m)
393 #define rwlock_try_read(m) _rwlock_try_read_debug(m, #m)
394 #define rwlock_try_write(m) _rwlock_try_write_debug(m, #m)
395 #define rwlock_unlock_read(m) _rwlock_unlock_read_debug(m, #m)
396 #define rwlock_unlock_write(m) _rwlock_unlock_write_debug(m, #m)
397 #define rwlock_assert_reading(m) _rwlock_assert_reading_debug(m, #m)
398 #define rwlock_assert_writing(m) _rwlock_assert_writing_debug(m, #m)
399 #define rwlock_assert_locked(m) _rwlock_assert_locked_debug(m, #m)
400 #define rwlock_assert_unlocked(m) _rwlock_assert_unlocked_debug(m, #m)
401
402 #endif
403
404 extern bool noSideTableLocksHeld(void);
405
406 #define rwlock_unlock(m, s) \
407 do { \
408 if ((s) == RDONLY) rwlock_unlock_read(m); \
409 else if ((s) == RDWR) rwlock_unlock_write(m); \
410 } while (0)
411
412
413 extern NXHashTable *class_hash;
414
415 #if !TARGET_OS_WIN32
416 /* nil handler object */
417 extern id _objc_nilReceiver;
418 extern id _objc_setNilReceiver(id newNilReceiver);
419 extern id _objc_getNilReceiver(void);
420 #endif
421
422 /* forward handler functions */
423 extern void *_objc_forward_handler;
424 extern void *_objc_forward_stret_handler;
425
426 /* tagged pointer support */
427 #if SUPPORT_TAGGED_POINTERS
428
429 #define OBJC_IS_TAGGED_PTR(PTR) ((uintptr_t)(PTR) & 0x1)
430 extern Class _objc_tagged_isa_table[16];
431
432 #else
433
434 #define OBJC_IS_TAGGED_PTR(PTR) 0
435
436 #endif
437
438
439 /* ignored selector support */
440
441 /* Non-GC: no ignored selectors
442 GC without fixup dispatch: some selectors ignored, remapped to kIgnore
443 GC with fixup dispatch: some selectors ignored, but not remapped
444 */
445
446 static inline int ignoreSelector(SEL sel)
447 {
448 #if !SUPPORT_GC
449 return NO;
450 #elif SUPPORT_IGNORED_SELECTOR_CONSTANT
451 return UseGC && sel == (SEL)kIgnore;
452 #else
453 return UseGC &&
454 (sel == @selector(retain) ||
455 sel == @selector(release) ||
456 sel == @selector(autorelease) ||
457 sel == @selector(retainCount) ||
458 sel == @selector(dealloc));
459 #endif
460 }
461
462 static inline int ignoreSelectorNamed(const char *sel)
463 {
464 #if !SUPPORT_GC
465 return NO;
466 #else
467 // release retain retainCount dealloc autorelease
468 return (UseGC &&
469 ( (sel[0] == 'r' && sel[1] == 'e' &&
470 (strcmp(&sel[2], "lease") == 0 ||
471 strcmp(&sel[2], "tain") == 0 ||
472 strcmp(&sel[2], "tainCount") == 0 ))
473 ||
474 (strcmp(sel, "dealloc") == 0)
475 ||
476 (sel[0] == 'a' && sel[1] == 'u' &&
477 strcmp(&sel[2], "torelease") == 0)));
478 #endif
479 }
480
481 /* Protocol implementation */
482 #if !__OBJC2__
483 struct old_protocol;
484 struct objc_method_description * lookup_protocol_method(struct old_protocol *proto, SEL aSel, BOOL isRequiredMethod, BOOL isInstanceMethod, BOOL recursive);
485 #else
486 Method _protocol_getMethod(Protocol *p, SEL sel, BOOL isRequiredMethod, BOOL isInstanceMethod, BOOL recursive);
487 #endif
488
489 /* GC startup */
490 extern void gc_init(BOOL wantsGC, BOOL wantsCompaction);
491 extern void gc_init2(void);
492
493 /* Exceptions */
494 struct alt_handler_list;
495 extern void exception_init(void);
496 extern void _destroyAltHandlerList(struct alt_handler_list *list);
497
498 /* Class change notifications (gdb only for now) */
499 #define OBJC_CLASS_ADDED (1<<0)
500 #define OBJC_CLASS_REMOVED (1<<1)
501 #define OBJC_CLASS_IVARS_CHANGED (1<<2)
502 #define OBJC_CLASS_METHODS_CHANGED (1<<3)
503 extern void gdb_objc_class_changed(Class cls, unsigned long changes, const char *classname)
504 __attribute__((noinline));
505
506 /* Write barrier implementations */
507 extern id objc_assign_strongCast_non_gc(id value, id *dest);
508 extern id objc_assign_global_non_gc(id value, id *dest);
509 extern id objc_assign_threadlocal_non_gc(id value, id *dest);
510 extern id objc_assign_ivar_non_gc(id value, id dest, ptrdiff_t offset);
511 extern id objc_assign_strongCast_gc(id val, id *dest);
512 extern id objc_assign_global_gc(id val, id *dest);
513 extern id objc_assign_threadlocal_gc(id val, id *dest);
514 extern id objc_assign_ivar_gc(id value, id dest, ptrdiff_t offset);
515
516 extern id objc_getAssociatedObject_non_gc(id object, const void *key);
517 extern void objc_setAssociatedObject_non_gc(id object, const void *key, id value, objc_AssociationPolicy policy);
518 extern id objc_getAssociatedObject_gc(id object, const void *key);
519 extern void objc_setAssociatedObject_gc(id object, const void *key, id value, objc_AssociationPolicy policy);
520
521 #if SUPPORT_GC
522
523 /* GC weak reference fixup. */
524 extern void gc_fixup_weakreferences(id newObject, id oldObject);
525
526 /* GC datasegment registration. */
527 extern void gc_register_datasegment(uintptr_t base, size_t size);
528 extern void gc_unregister_datasegment(uintptr_t base, size_t size);
529 extern void gc_fixup_barrier_stubs(const struct dyld_image_info *info);
530
531 /* objc_dumpHeap implementation */
532 extern BOOL _objc_dumpHeap(auto_zone_t *zone, const char *filename);
533
534 /*
535 objc_assign_ivar, objc_assign_global, objc_assign_threadlocal, and objc_assign_strongCast MUST NOT be called directly
536 from inside libobjc. They live in the data segment, and must be called through the
537 following pointer(s) for libobjc to exist in the shared cache.
538
539 Note: If we build with GC enabled, gcc will emit calls to the original functions, which will break this.
540 */
541
542 extern id (*objc_assign_ivar_internal)(id, id, ptrdiff_t);
543
544 #endif
545
546 /* Code modification */
547 extern size_t objc_branch_size(void *entry, void *target);
548 extern size_t objc_write_branch(void *entry, void *target);
549 extern size_t objc_cond_branch_size(void *entry, void *target, unsigned cond);
550 extern size_t objc_write_cond_branch(void *entry, void *target, unsigned cond);
551 #if defined(__i386__) || defined(__x86_64__)
552 #define COND_ALWAYS 0xE9 /* JMP rel32 */
553 #define COND_NE 0x85 /* JNE rel32 (0F 85) */
554 #endif
555
556
557 // Settings from environment variables
558 #if !SUPPORT_ENVIRON
559 # define ENV(x) enum { x = 0 }
560 #else
561 # define ENV(x) extern int x
562 #endif
563 ENV(PrintImages); // env OBJC_PRINT_IMAGES
564 ENV(PrintLoading); // env OBJC_PRINT_LOAD_METHODS
565 ENV(PrintInitializing); // env OBJC_PRINT_INITIALIZE_METHODS
566 ENV(PrintResolving); // env OBJC_PRINT_RESOLVED_METHODS
567 ENV(PrintConnecting); // env OBJC_PRINT_CLASS_SETUP
568 ENV(PrintProtocols); // env OBJC_PRINT_PROTOCOL_SETUP
569 ENV(PrintIvars); // env OBJC_PRINT_IVAR_SETUP
570 ENV(PrintVtables); // env OBJC_PRINT_VTABLE_SETUP
571 ENV(PrintVtableImages); // env OBJC_PRINT_VTABLE_IMAGES
572 ENV(PrintFuture); // env OBJC_PRINT_FUTURE_CLASSES
573 ENV(PrintGC); // env OBJC_PRINT_GC
574 ENV(PrintPreopt); // env OBJC_PRINT_PREOPTIMIZATION
575 ENV(PrintCxxCtors); // env OBJC_PRINT_CXX_CTORS
576 ENV(PrintExceptions); // env OBJC_PRINT_EXCEPTIONS
577 ENV(PrintExceptionThrow); // env OBJC_PRINT_EXCEPTION_THROW
578 ENV(PrintAltHandlers); // env OBJC_PRINT_ALT_HANDLERS
579 ENV(PrintDeprecation); // env OBJC_PRINT_DEPRECATION_WARNINGS
580 ENV(PrintReplacedMethods); // env OBJC_PRINT_REPLACED_METHODS
581 ENV(PrintCaches); // env OBJC_PRINT_CACHE_SETUP
582 ENV(PrintPoolHiwat); // env OBJC_PRINT_POOL_HIGHWATER
583 ENV(PrintCustomRR); // env OBJC_PRINT_CUSTOM_RR
584 ENV(PrintCustomAWZ); // env OBJC_PRINT_CUSTOM_AWZ
585 ENV(UseInternalZone); // env OBJC_USE_INTERNAL_ZONE
586
587 ENV(DebugUnload); // env OBJC_DEBUG_UNLOAD
588 ENV(DebugFragileSuperclasses); // env OBJC_DEBUG_FRAGILE_SUPERCLASSES
589 ENV(DebugFinalizers); // env OBJC_DEBUG_FINALIZERS
590 ENV(DebugNilSync); // env OBJC_DEBUG_NIL_SYNC
591 ENV(DebugNonFragileIvars); // env OBJC_DEBUG_NONFRAGILE_IVARS
592 ENV(DebugAltHandlers); // env OBJC_DEBUG_ALT_HANDLERS
593
594 ENV(DisableGC); // env OBJC_DISABLE_GC
595 ENV(DisableVtables); // env OBJC_DISABLE_VTABLES
596 ENV(DisablePreopt); // env OBJC_DISABLE_PREOPTIMIZATION
597
598 #undef ENV
599
600 extern void environ_init(void);
601
602 extern void logReplacedMethod(const char *className, SEL s, BOOL isMeta, const char *catName, IMP oldImp, IMP newImp);
603
604 static __inline uint32_t _objc_strhash(const char *s) {
605 uint32_t hash = 0;
606 for (;;) {
607 int a = *s++;
608 if (0 == a) break;
609 hash += (hash << 8) + a;
610 }
611 return hash;
612 }
613
614
615 // objc per-thread storage
616 typedef struct {
617 struct _objc_initializing_classes *initializingClasses; // for +initialize
618 struct SyncCache *syncCache; // for @synchronize
619 struct alt_handler_list *handlerList; // for exception alt handlers
620
621 // If you add new fields here, don't forget to update
622 // _objc_pthread_destroyspecific()
623
624 } _objc_pthread_data;
625
626 extern _objc_pthread_data *_objc_fetch_pthread_data(BOOL create);
627 extern void tls_init(void);
628
629
630 // cache.h
631 #if TARGET_OS_WIN32
632
633 #else
634 static inline int isPowerOf2(unsigned long l) { return 1 == __builtin_popcountl(l); }
635 #endif
636 extern void flush_caches(Class cls, BOOL flush_meta);
637 extern void flush_cache(Class cls);
638 extern BOOL _cache_fill(Class cls, Method smt, SEL sel);
639 extern void _cache_addForwardEntry(Class cls, SEL sel);
640 extern IMP _cache_addIgnoredEntry(Class cls, SEL sel);
641 extern void _cache_free(Cache cache);
642 extern void _cache_collect(bool collectALot);
643
644 extern mutex_t cacheUpdateLock;
645
646 // encoding.h
647 extern unsigned int encoding_getNumberOfArguments(const char *typedesc);
648 extern unsigned int encoding_getSizeOfArguments(const char *typedesc);
649 extern unsigned int encoding_getArgumentInfo(const char *typedesc, unsigned int arg, const char **type, int *offset);
650 extern void encoding_getReturnType(const char *t, char *dst, size_t dst_len);
651 extern char * encoding_copyReturnType(const char *t);
652 extern void encoding_getArgumentType(const char *t, unsigned int index, char *dst, size_t dst_len);
653 extern char *encoding_copyArgumentType(const char *t, unsigned int index);
654
655 // sync.h
656 extern void _destroySyncCache(struct SyncCache *cache);
657
658 // arr
659 extern void (^objc_arr_log)(const char *, id param);
660 extern void arr_init(void);
661 extern id objc_autoreleaseReturnValue(id obj);
662
663
664 // layout.h
665 typedef struct {
666 uint8_t *bits;
667 size_t bitCount;
668 size_t bitsAllocated;
669 BOOL weak;
670 } layout_bitmap;
671 extern layout_bitmap layout_bitmap_create(const unsigned char *layout_string, size_t layoutStringInstanceSize, size_t instanceSize, BOOL weak);
672 extern layout_bitmap layout_bitmap_create_empty(size_t instanceSize, BOOL weak);
673 extern void layout_bitmap_free(layout_bitmap bits);
674 extern const unsigned char *layout_string_create(layout_bitmap bits);
675 extern void layout_bitmap_set_ivar(layout_bitmap bits, const char *type, size_t offset);
676 extern void layout_bitmap_grow(layout_bitmap *bits, size_t newCount);
677 extern void layout_bitmap_slide(layout_bitmap *bits, size_t oldPos, size_t newPos);
678 extern void layout_bitmap_slide_anywhere(layout_bitmap *bits, size_t oldPos, size_t newPos);
679 extern BOOL layout_bitmap_splat(layout_bitmap dst, layout_bitmap src,
680 size_t oldSrcInstanceSize);
681 extern BOOL layout_bitmap_or(layout_bitmap dst, layout_bitmap src, const char *msg);
682 extern BOOL layout_bitmap_clear(layout_bitmap dst, layout_bitmap src, const char *msg);
683 extern void layout_bitmap_print(layout_bitmap bits);
684
685
686 // fixme runtime
687 extern id look_up_class(const char *aClassName, BOOL includeUnconnected, BOOL includeClassHandler);
688 extern const char *map_images(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
689 extern const char *map_images_nolock(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
690 extern const char * load_images(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
691 extern BOOL load_images_nolock(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
692 extern void unmap_image(const struct mach_header *mh, intptr_t vmaddr_slide);
693 extern void unmap_image_nolock(const struct mach_header *mh);
694 extern void _read_images(header_info **hList, uint32_t hCount);
695 extern void prepare_load_methods(header_info *hi);
696 extern void _unload_image(header_info *hi);
697 extern const char ** _objc_copyClassNamesForImage(header_info *hi, unsigned int *outCount);
698
699 extern Class _objc_allocateFutureClass(const char *name);
700
701
702 extern const header_info *_headerForClass(Class cls);
703
704 extern Class _class_getSuperclass(Class cls);
705 extern Class _class_remap(Class cls);
706 extern BOOL _class_getInfo(Class cls, int info);
707 extern const char *_class_getName(Class cls);
708 extern size_t _class_getInstanceSize(Class cls);
709 extern Class _class_getMeta(Class cls);
710 extern BOOL _class_isMetaClass(Class cls);
711 extern Cache _class_getCache(Class cls);
712 extern void _class_setCache(Class cls, Cache cache);
713 extern BOOL _class_isInitializing(Class cls);
714 extern BOOL _class_isInitialized(Class cls);
715 extern void _class_setInitializing(Class cls);
716 extern void _class_setInitialized(Class cls);
717 extern Class _class_getNonMetaClass(Class cls, id obj);
718 extern Method _class_getMethod(Class cls, SEL sel);
719 extern Method _class_getMethodNoSuper(Class cls, SEL sel);
720 extern Method _class_getMethodNoSuper_nolock(Class cls, SEL sel);
721 extern BOOL _class_isLoadable(Class cls);
722 extern IMP _class_getLoadMethod(Class cls);
723 extern BOOL _class_hasLoadMethod(Class cls);
724 extern BOOL _class_hasCxxStructors(Class cls);
725 extern BOOL _class_shouldFinalizeOnMainThread(Class cls);
726 extern void _class_setFinalizeOnMainThread(Class cls);
727 extern BOOL _class_instancesHaveAssociatedObjects(Class cls);
728 extern void _class_setInstancesHaveAssociatedObjects(Class cls);
729 extern BOOL _class_shouldGrowCache(Class cls);
730 extern void _class_setGrowCache(Class cls, BOOL grow);
731 extern Ivar _class_getVariable(Class cls, const char *name, Class *memberOf);
732 extern BOOL _class_usesAutomaticRetainRelease(Class cls);
733 extern uint32_t _class_getInstanceStart(Class cls);
734
735 extern unsigned _class_createInstancesFromZone(Class cls, size_t extraBytes, void *zone, id *results, unsigned num_requested);
736 extern id _objc_constructOrFree(Class cls, void *bytes);
737
738 extern const char *_category_getName(Category cat);
739 extern const char *_category_getClassName(Category cat);
740 extern Class _category_getClass(Category cat);
741 extern IMP _category_getLoadMethod(Category cat);
742
743 extern BOOL object_cxxConstruct(id obj);
744 extern void object_cxxDestruct(id obj);
745
746 extern Method _class_resolveMethod(Class cls, SEL sel);
747 extern void log_and_fill_cache(Class cls, Class implementer, Method meth, SEL sel);
748
749 #define OBJC_WARN_DEPRECATED \
750 do { \
751 static int warned = 0; \
752 if (!warned) { \
753 warned = 1; \
754 _objc_inform_deprecated(__FUNCTION__, NULL); \
755 } \
756 } while (0) \
757
758 __END_DECLS
759
760
761 #ifndef STATIC_ASSERT
762 # define STATIC_ASSERT(x) _STATIC_ASSERT2(x, __LINE__)
763 # define _STATIC_ASSERT2(x, line) _STATIC_ASSERT3(x, line)
764 # define _STATIC_ASSERT3(x, line) \
765 typedef struct { \
766 int _static_assert[(x) ? 0 : -1]; \
767 } _static_assert_ ## line __attribute__((unavailable))
768 #endif
769
770
771 /***********************************************************************
772 * object_getClass.
773 * Locking: None. If you add locking, tell gdb (rdar://7516456).
774 **********************************************************************/
775 static inline Class _object_getClass(id obj)
776 {
777 #if SUPPORT_TAGGED_POINTERS
778 if (OBJC_IS_TAGGED_PTR(obj)) {
779 uint8_t slotNumber = ((uint8_t) (uint64_t) obj) & 0x0F;
780 Class isa = _objc_tagged_isa_table[slotNumber];
781 return isa;
782 }
783 #endif
784 if (obj) return obj->isa;
785 else return Nil;
786 }
787
788
789 // Global operator new and delete. We must not use any app overrides.
790 // This ALSO REQUIRES each of these be in libobjc's unexported symbol list.
791 #if __cplusplus
792 #include <new>
793 inline void* operator new(std::size_t size) throw (std::bad_alloc) { return _malloc_internal(size); }
794 inline void* operator new[](std::size_t size) throw (std::bad_alloc) { return _malloc_internal(size); }
795 inline void* operator new(std::size_t size, const std::nothrow_t&) throw() { return _malloc_internal(size); }
796 inline void* operator new[](std::size_t size, const std::nothrow_t&) throw() { return _malloc_internal(size); }
797 inline void operator delete(void* p) throw() { _free_internal(p); }
798 inline void operator delete[](void* p) throw() { _free_internal(p); }
799 inline void operator delete(void* p, const std::nothrow_t&) throw() { _free_internal(p); }
800 inline void operator delete[](void* p, const std::nothrow_t&) throw() { _free_internal(p); }
801 #endif
802
803
804 #endif /* _OBJC_PRIVATE_H_ */
805