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_ */