2  * Copyright (c) 1999-2007 Apple Inc.  All Rights Reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   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 
  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. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  25  *      Copyright 1988-1996, NeXT Software, Inc. 
  28 #ifndef _OBJC_PRIVATE_H_ 
  29 #define _OBJC_PRIVATE_H_ 
  36 #include "hashtable2.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" 
  45 #include "objc-auto.h" 
  47 #define __APPLE_API_PRIVATE 
  49 #undef __APPLE_API_PRIVATE 
  51 /* Do not include message.h here. */ 
  52 /* #include "message.h" */ 
  58 #   define WORD_SHIFT 3UL 
  59 #   define WORD_MASK 7UL 
  61 #   define WORD_SHIFT 2UL 
  62 #   define WORD_MASK 3UL 
  65 #if (defined(OBJC_NO_GC) && SUPPORT_GC)  ||  \ 
  66     (!defined(OBJC_NO_GC) && !SUPPORT_GC) 
  67 #   error OBJC_NO_GC and SUPPORT_GC inconsistent 
  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(); 
  81 #   define UseCompaction NO 
  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 
  96 typedef struct objc_cache 
*Cache
; 
  98 // definition in runtime.h 
 103     uint32_t version
; // currently 0 
 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) 
 115 #define _objcHeaderIsReplacement(h)  ((h)->info  &&  ((h)->info->flags & OBJC_IMAGE_IS_REPLACEMENT)) 
 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? 
 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)) 
 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 
 142 #define _objcHeaderOptimizedByDyld(h)  ((h)->info  &&  ((h)->info->flags & OBJC_IMAGE_OPTIMIZED_BY_DYLD)) 
 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. 
 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 
 157     bool allClassesRealized
; 
 159     // Do not add fields without editing ObjCModernAbstraction.hpp 
 162     struct old_protocol 
**proto_refs
; 
 163     struct objc_module 
*mod_ptr
; 
 166     struct objc_module 
**modules
; 
 168     struct old_protocol 
**protocols
; 
 169     size_t protocolCount
; 
 171     size_t imageinfoBytes
; 
 174     struct objc_class 
**clsrefs
; 
 181 extern header_info 
*FirstHeader
; 
 182 extern header_info 
*LastHeader
; 
 183 extern int HeaderCount
; 
 185 extern void appendHeader(header_info 
*hi
); 
 186 extern void removeHeader(header_info 
*hi
); 
 188 extern objc_image_info 
*_getObjcImageInfo(const headerType 
*head
, size_t *size
); 
 189 extern BOOL 
_hasObjcContents(const header_info 
*hi
); 
 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
); 
 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
; 
 213 extern SEL SEL_finalize
; 
 214 extern SEL SEL_forwardInvocation
; 
 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
); 
 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
); 
 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
); 
 242 extern Class 
_calloc_class(size_t size
); 
 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
); 
 249 extern IMP 
_cache_getImp(Class cls
, SEL sel
); 
 250 extern Method 
_cache_getMethod(Class cls
, SEL sel
, IMP objc_msgForward_internal_imp
); 
 252 /* message dispatcher */ 
 253 extern IMP 
_class_lookupMethodAndLoadCache3(id
, SEL
, Class
); 
 255 #if !OBJC_OLD_DISPATCH_PROTOTYPES 
 256 extern void _objc_msgForward_internal(void); 
 257 extern void _objc_ignored_method(void); 
 259 extern id 
_objc_msgForward_internal(id
, SEL
, ...); 
 260 extern id 
_objc_ignored_method(id
, SEL
, ...); 
 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
); 
 274 extern Class 
_objc_getFreedObjectClass (void); 
 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
); 
 280 /* hash table additions */ 
 281 extern unsigned _NXHashCapacity(NXHashTable 
*table
); 
 282 extern void _NXHashRehashToCapacity(NXHashTable 
*table
, unsigned newCapacity
); 
 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
); 
 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
; 
 298 extern rwlock_t runtimeLock
; 
 300 extern mutex_t classLock
; 
 301 extern mutex_t methodListLock
; 
 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); 
 311 #if defined(NDEBUG)  ||  TARGET_OS_WIN32 
 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) 
 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) 
 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) 
 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) 
 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
); 
 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
); 
 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
); 
 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
); 
 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) 
 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) 
 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) 
 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) 
 404 extern bool noSideTableLocksHeld(void); 
 406 #define rwlock_unlock(m, s)                           \ 
 408         if ((s) == RDONLY) rwlock_unlock_read(m);     \ 
 409         else if ((s) == RDWR) rwlock_unlock_write(m); \ 
 413 extern NXHashTable 
*class_hash
; 
 416 /* nil handler object */ 
 417 extern id _objc_nilReceiver
; 
 418 extern id 
_objc_setNilReceiver(id newNilReceiver
); 
 419 extern id 
_objc_getNilReceiver(void); 
 422 /* forward handler functions */ 
 423 extern void *_objc_forward_handler
; 
 424 extern void *_objc_forward_stret_handler
; 
 426 /* tagged pointer support */ 
 427 #if SUPPORT_TAGGED_POINTERS 
 429 #define OBJC_IS_TAGGED_PTR(PTR)         ((uintptr_t)(PTR) & 0x1) 
 430 extern Class _objc_tagged_isa_table
[16]; 
 434 #define OBJC_IS_TAGGED_PTR(PTR)         0 
 439 /* ignored selector support */ 
 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  
 446 static inline int ignoreSelector(SEL sel
) 
 450 #elif SUPPORT_IGNORED_SELECTOR_CONSTANT 
 451     return UseGC  
&&  sel 
== (SEL
)kIgnore
; 
 454         (sel 
== @
selector(retain
)       ||   
 455          sel 
== @
selector(release
)      ||   
 456          sel 
== @
selector(autorelease
)  ||   
 457          sel 
== @
selector(retainCount
)  ||   
 458          sel 
== @
selector(dealloc
)); 
 462 static inline int ignoreSelectorNamed(const char *sel
) 
 467     // release retain retainCount dealloc autorelease 
 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 )) 
 474                (strcmp(sel
, "dealloc") == 0) 
 476                (sel
[0] == 'a' && sel
[1] == 'u' &&  
 477                 strcmp(&sel
[2], "torelease") == 0))); 
 481 /* Protocol implementation */ 
 484 struct objc_method_description 
* lookup_protocol_method(struct old_protocol 
*proto
, SEL aSel
, BOOL isRequiredMethod
, BOOL isInstanceMethod
, BOOL recursive
); 
 486 Method 
_protocol_getMethod(Protocol 
*p
, SEL sel
, BOOL isRequiredMethod
, BOOL isInstanceMethod
, BOOL recursive
); 
 490 extern void gc_init(BOOL wantsGC
, BOOL wantsCompaction
); 
 491 extern void gc_init2(void); 
 494 struct alt_handler_list
; 
 495 extern void exception_init(void); 
 496 extern void _destroyAltHandlerList(struct alt_handler_list 
*list
); 
 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
)); 
 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
); 
 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
); 
 523 /* GC weak reference fixup. */ 
 524 extern void gc_fixup_weakreferences(id newObject
, id oldObject
); 
 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
); 
 531 /* objc_dumpHeap implementation */ 
 532 extern BOOL 
_objc_dumpHeap(auto_zone_t 
*zone
, const char *filename
); 
 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. 
 539     Note: If we build with GC enabled, gcc will emit calls to the original functions, which will break this. 
 542 extern id (*objc_assign_ivar_internal
)(id
, id
, ptrdiff_t); 
 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) */ 
 557 // Settings from environment variables 
 559 #   define ENV(x) enum { x = 0 } 
 561 #   define ENV(x) extern int x 
 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 
 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 
 594 ENV(DisableGC
);                 // env OBJC_DISABLE_GC 
 595 ENV(DisableVtables
);            // env OBJC_DISABLE_VTABLES 
 596 ENV(DisablePreopt
);             // env OBJC_DISABLE_PREOPTIMIZATION 
 600 extern void environ_init(void); 
 602 extern void logReplacedMethod(const char *className
, SEL s
, BOOL isMeta
, const char *catName
, IMP oldImp
, IMP newImp
); 
 604 static __inline 
uint32_t _objc_strhash(const char *s
) { 
 609         hash 
+= (hash 
<< 8) + a
; 
 615 // objc per-thread storage 
 617     struct _objc_initializing_classes 
*initializingClasses
; // for +initialize 
 618     struct SyncCache 
*syncCache
;  // for @synchronize 
 619     struct alt_handler_list 
*handlerList
;  // for exception alt handlers 
 621     // If you add new fields here, don't forget to update  
 622     // _objc_pthread_destroyspecific() 
 624 } _objc_pthread_data
; 
 626 extern _objc_pthread_data 
*_objc_fetch_pthread_data(BOOL create
); 
 627 extern void tls_init(void); 
 634 static inline int isPowerOf2(unsigned long l
) { return 1 == __builtin_popcountl(l
); } 
 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
); 
 644 extern mutex_t cacheUpdateLock
; 
 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
); 
 656 extern void _destroySyncCache(struct SyncCache 
*cache
); 
 659 extern void (^objc_arr_log
)(const char *, id param
); 
 660 extern void arr_init(void); 
 661 extern id 
objc_autoreleaseReturnValue(id obj
); 
 668     size_t bitsAllocated
; 
 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
); 
 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
); 
 699 extern Class 
_objc_allocateFutureClass(const char *name
); 
 702 extern const header_info 
*_headerForClass(Class cls
); 
 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
); 
 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
); 
 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
); 
 743 extern BOOL 
object_cxxConstruct(id obj
); 
 744 extern void object_cxxDestruct(id obj
); 
 746 extern Method 
_class_resolveMethod(Class cls
, SEL sel
); 
 747 extern void log_and_fill_cache(Class cls
, Class implementer
, Method meth
, SEL sel
); 
 749 #define OBJC_WARN_DEPRECATED \ 
 751         static int warned = 0; \ 
 754             _objc_inform_deprecated(__FUNCTION__, NULL); \ 
 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)                                     \ 
 766             int _static_assert[(x) ? 0 : -1];                           \ 
 767         } _static_assert_ ## line __attribute__((unavailable))  
 771 /*********************************************************************** 
 773 * Locking: None. If you add locking, tell gdb (rdar://7516456). 
 774 **********************************************************************/ 
 775 static inline Class 
_object_getClass(id obj
) 
 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
]; 
 784     if (obj
) return obj
->isa
; 
 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. 
 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
); } 
 804 #endif /* _OBJC_PRIVATE_H_ */