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"
40 #include "objc-references.h"
41 #include "objc-initialize.h"
42 #include "objc-loadmethod.h"
43 #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" */
57 #if defined(OBJC_NO_GC) != defined(NO_GC)
58 # error OBJC_NO_GC and NO_GC inconsistent
62 # include <auto_zone.h>
63 extern BOOL UseGC
; // equivalent to calling objc_collecting_enabled()
64 extern auto_zone_t
*gc_zone
; // the GC zone, or NULL if no GC
65 extern void objc_addRegisteredClass(Class c
);
66 extern void objc_removeRegisteredClass(Class c
);
70 # define objc_assign_ivar_internal objc_assign_ivar
71 # define objc_addRegisteredClass(c) do {} while(0)
72 # define objc_removeRegisteredClass(c) do {} while(0)
73 /* Uses of the following must be protected with UseGC. */
74 extern id
gc_unsupported_dont_call();
75 # define auto_zone_allocate_object gc_unsupported_dont_call
76 # define auto_zone_retain gc_unsupported_dont_call
77 # define auto_zone_release gc_unsupported_dont_call
78 # define auto_zone_is_valid_pointer gc_unsupported_dont_call
79 # define auto_zone_write_barrier_memmove gc_unsupported_dont_call
80 # define AUTO_OBJECT_SCANNED 0
84 struct old_method_list
;
92 typedef struct objc_module
*Module
;
93 typedef struct objc_cache
*Cache
;
101 struct old_class
*isa
;
102 struct old_class
*super_class
;
107 struct old_ivar_list
*ivars
;
108 struct old_method_list
**methodLists
;
110 struct old_protocol_list
*protocols
;
112 const char *ivar_layout
;
113 struct old_class_ext
*ext
;
116 struct old_class_ext
{
118 const char *weak_ivar_layout
;
119 struct objc_property_list
**propertyLists
;
122 struct old_category
{
125 struct old_method_list
*instance_methods
;
126 struct old_method_list
*class_methods
;
127 struct old_protocol_list
*protocols
;
129 struct objc_property_list
*instance_properties
;
141 struct old_ivar_list
{
146 /* variable length structure */
147 struct old_ivar ivar_list
[1];
157 struct old_method_list
{
158 struct old_method_list
*obsolete
;
164 /* variable length structure */
165 struct old_method method_list
[1];
168 struct old_protocol
{
170 const char *protocol_name
;
171 struct old_protocol_list
*protocol_list
;
172 struct objc_method_description_list
*instance_methods
;
173 struct objc_method_description_list
*class_methods
;
176 struct old_protocol_list
{
177 struct old_protocol_list
*next
;
179 struct old_protocol
*list
[1];
182 struct old_protocol_ext
{
184 struct objc_method_description_list
*optional_instance_methods
;
185 struct objc_method_description_list
*optional_class_methods
;
186 struct objc_property_list
*instance_properties
;
191 typedef objc_property_t Property
;
193 struct objc_property
{
195 const char *attributes
;
198 struct objc_property_list
{
201 struct objc_property first
;
205 uint32_t version
; // currently 0
209 // masks for objc_image_info.flags
210 #define OBJC_IMAGE_IS_REPLACEMENT (1<<0)
211 #define OBJC_IMAGE_SUPPORTS_GC (1<<1)
212 #define OBJC_IMAGE_REQUIRES_GC (1<<2)
213 #define OBJC_IMAGE_OPTIMIZED_BY_DYLD (1<<3)
216 #define _objcHeaderIsReplacement(h) ((h)->info && ((h)->info->flags & OBJC_IMAGE_IS_REPLACEMENT))
218 /* OBJC_IMAGE_IS_REPLACEMENT:
219 Don't load any classes
220 Don't load any categories
221 Do fix up selector refs (@selector points to them)
222 Do fix up class refs (@class and objc_msgSend points to them)
223 Do fix up protocols (@protocol points to them)
224 Do fix up super_class pointers in classes ([super ...] points to them)
225 Future: do load new classes?
226 Future: do load new categories?
227 Future: do insert new methods on existing classes?
228 Future: do insert new methods on existing categories?
231 #define _objcInfoSupportsGC(info) (((info)->flags & OBJC_IMAGE_SUPPORTS_GC) ? 1 : 0)
232 #define _objcInfoRequiresGC(info) (((info)->flags & OBJC_IMAGE_REQUIRES_GC) ? 1 : 0)
233 #define _objcHeaderSupportsGC(h) ((h)->info && _objcInfoSupportsGC((h)->info))
234 #define _objcHeaderRequiresGC(h) ((h)->info && _objcInfoRequiresGC((h)->info))
236 /* OBJC_IMAGE_SUPPORTS_GC:
237 was compiled with -fobjc-gc flag, regardless of whether write-barriers were issued
238 if executable image compiled this way, then all subsequent libraries etc. must also be this way
241 #define _objcHeaderOptimizedByDyld(h) ((h)->info && ((h)->info->flags & OBJC_IMAGE_OPTIMIZED_BY_DYLD))
243 /* OBJC_IMAGE_OPTIMIZED_BY_DYLD:
244 Assorted metadata precooked in the dyld shared cache.
245 Never set for images outside the shared cache file itself.
249 typedef struct _header_info
{
250 struct _header_info
*next
;
251 const headerType
* mhdr
;
252 struct objc_module
*mod_ptr
;
254 const objc_image_info
*info
;
255 BOOL allClassesRealized
;
259 extern header_info
*FirstHeader
;
260 extern header_info
*LastHeader
;
261 extern int HeaderCount
;
263 extern void _objc_appendHeader(header_info
*hi
);
264 extern void _objc_removeHeader(header_info
*hi
);
265 extern const char *_nameForHeader(const headerType
*);
267 extern objc_image_info
*_getObjcImageInfo(const headerType
*head
, ptrdiff_t slide
, size_t *size
);
268 extern const char *_getObjcHeaderName(const headerType
*head
);
269 extern ptrdiff_t _getImageSlide(const headerType
*header
);
272 extern Module
_getObjcModules(const header_info
*hi
, size_t *count
);
273 extern SEL
*_getObjcSelectorRefs(const header_info
*hi
, size_t *count
);
274 extern BOOL
_hasObjcContents(const header_info
*hi
);
276 extern struct old_protocol
**_getObjcProtocols(const header_info
*head
, size_t *count
);
277 extern struct old_class
**_getObjcClassRefs(const header_info
*hi
, size_t *count
);
278 extern const char *_getObjcClassNames(const header_info
*hi
, size_t *size
);
282 extern SEL
*_getObjc2SelectorRefs(const header_info
*hi
, size_t *count
);
283 extern message_ref
*_getObjc2MessageRefs(const header_info
*hi
, size_t *count
);extern struct class_t
**_getObjc2ClassRefs(const header_info
*hi
, size_t *count
);
284 extern struct class_t
**_getObjc2SuperRefs(const header_info
*hi
, size_t *count
);
285 extern struct class_t
**_getObjc2ClassList(const header_info
*hi
, size_t *count
);
286 extern struct class_t
**_getObjc2NonlazyClassList(const header_info
*hi
, size_t *count
);
287 extern struct category_t
**_getObjc2CategoryList(const header_info
*hi
, size_t *count
);
288 extern struct category_t
**_getObjc2NonlazyCategoryList(const header_info
*hi
, size_t *count
);
289 extern struct protocol_t
**_getObjc2ProtocolList(const header_info
*head
, size_t *count
);
290 extern struct protocol_t
**_getObjc2ProtocolRefs(const header_info
*head
, size_t *count
);
293 #define END_OF_METHODS_LIST ((struct old_method_list*)-1)
297 extern void sel_init(BOOL gc
);
298 extern SEL
sel_registerNameNoLock(const char *str
, BOOL copy
);
299 extern void sel_lock(void);
300 extern void sel_unlock(void);
301 extern BOOL
sel_preoptimizationValid(const header_info
*hi
);
302 extern void disableSelectorPreoptimization(void);
305 extern SEL SEL_initialize
;
306 extern SEL SEL_resolveClassMethod
;
307 extern SEL SEL_resolveInstanceMethod
;
308 extern SEL SEL_cxx_construct
;
309 extern SEL SEL_cxx_destruct
;
310 extern SEL SEL_retain
;
311 extern SEL SEL_release
;
312 extern SEL SEL_autorelease
;
314 extern SEL SEL_finalize
;
317 /* optional malloc zone for runtime data */
318 extern malloc_zone_t
*_objc_internal_zone(void);
319 extern void *_malloc_internal(size_t size
);
320 extern void *_calloc_internal(size_t count
, size_t size
);
321 extern void *_realloc_internal(void *ptr
, size_t size
);
322 extern char *_strdup_internal(const char *str
);
323 extern char *_strdupcat_internal(const char *s1
, const char *s2
);
324 extern void *_memdup_internal(const void *mem
, size_t size
);
325 extern void _free_internal(void *ptr
);
327 extern Class
_calloc_class(size_t size
);
330 extern Class
objc_getOrigClass (const char *name
);
331 extern IMP
lookupNamedMethodInMethodList(struct old_method_list
*mlist
, const char *meth_name
);
332 extern void _objc_insertMethods(struct old_class
*cls
, struct old_method_list
*mlist
, struct old_category
*cat
);
333 extern void _objc_removeMethods(struct old_class
*cls
, struct old_method_list
*mlist
);
334 extern void _objc_flush_caches (Class cls
);
335 extern void _class_addProperties(struct old_class
*cls
, struct objc_property_list
*additions
);
336 extern void change_class_references(struct old_class
*imposter
, struct old_class
*original
, struct old_class
*copy
, BOOL changeSuperRefs
);
337 extern void flush_marked_caches(void);
338 extern void set_superclass(struct old_class
*cls
, struct old_class
*supercls
);
341 extern IMP
lookUpMethod(Class
, SEL
, BOOL initialize
, BOOL cache
);
342 extern void lockForMethodLookup(void);
343 extern void unlockForMethodLookup(void);
344 extern IMP
prepareForMethodLookup(Class cls
, SEL sel
, BOOL initialize
);
346 extern IMP
_cache_getImp(Class cls
, SEL sel
);
347 extern Method
_cache_getMethod(Class cls
, SEL sel
, IMP objc_msgForward_internal_imp
);
349 /* message dispatcher */
350 extern IMP
_class_lookupMethodAndLoadCache(Class
, SEL
);
351 extern id
_objc_msgForward_internal(id self
, SEL sel
, ...);
352 extern id
_objc_ignored_method(id self
, SEL _cmd
);
355 extern void __objc_error(id
, const char *, ...) __attribute__((format (printf
, 2, 3)));
356 extern void _objc_inform(const char *fmt
, ...) __attribute__((format (printf
, 1, 2)));
357 extern void _objc_inform_on_crash(const char *fmt
, ...) __attribute__((format (printf
, 1, 2)));
358 extern void _objc_inform_now_and_on_crash(const char *fmt
, ...) __attribute__((format (printf
, 1, 2)));
359 extern void _objc_warn_deprecated(const char *oldname
, const char *newname
) __attribute__((noinline
));
360 extern void _objc_error(id
, const char *, va_list);
361 extern void inform_duplicate(const char *name
, Class oldCls
, Class cls
);
364 extern Class
_objc_getFreedObjectClass (void);
365 #ifndef OBJC_INSTRUMENTED
366 extern const struct objc_cache _objc_empty_cache
;
368 extern struct objc_cache _objc_empty_cache
;
371 extern IMP _objc_empty_vtable
[128];
374 /* map table additions */
375 extern void *NXMapKeyCopyingInsert(NXMapTable
*table
, const void *key
, const void *value
);
376 extern void *NXMapKeyFreeingRemove(NXMapTable
*table
, const void *key
);
379 /* Every lock used anywhere must be declared here.
380 * Locks not declared here may cause gdb deadlocks. */
381 extern void lock_init(void);
382 extern rwlock_t selLock
;
383 extern mutex_t cacheUpdateLock
;
384 extern recursive_mutex_t loadMethodLock
;
386 extern rwlock_t runtimeLock
;
388 extern mutex_t classLock
;
389 extern mutex_t methodListLock
;
392 /* Debugger mode for gdb */
393 #define DEBUGGER_OFF 0
394 #define DEBUGGER_PARTIAL 1
395 #define DEBUGGER_FULL 2
396 extern int startDebuggerMode(void);
397 extern void endDebuggerMode(void);
399 #if defined(NDEBUG) || TARGET_OS_WIN32
401 #define _destroyLockList(x) do { } while (0)
403 #define mutex_lock(m) _mutex_lock_nodebug(m)
404 #define mutex_try_lock(m) _mutex_try_lock_nodebug(m)
405 #define mutex_unlock(m) _mutex_unlock_nodebug(m)
406 #define mutex_assert_locked(m) do { } while (0)
407 #define mutex_assert_unlocked(m) do { } while (0)
409 #define recursive_mutex_lock(m) _recursive_mutex_lock_nodebug(m)
410 #define recursive_mutex_try_lock(m) _recursive_mutex_try_lock_nodebug(m)
411 #define recursive_mutex_unlock(m) _recursive_mutex_unlock_nodebug(m)
412 #define recursive_mutex_assert_locked(m) do { } while (0)
413 #define recursive_mutex_assert_unlocked(m) do { } while (0)
415 #define monitor_enter(m) _monitor_enter_nodebug(m)
416 #define monitor_exit(m) _monitor_exit_nodebug(m)
417 #define monitor_wait(m) _monitor_wait_nodebug(m)
418 #define monitor_assert_locked(m) do { } while (0)
419 #define monitor_assert_unlocked(m) do { } while (0)
421 #define rwlock_read(m) _rwlock_read_nodebug(m)
422 #define rwlock_write(m) _rwlock_write_nodebug(m)
423 #define rwlock_try_read(m) _rwlock_try_read_nodebug(m)
424 #define rwlock_try_write(m) _rwlock_try_write_nodebug(m)
425 #define rwlock_unlock_read(m) _rwlock_unlock_read_nodebug(m)
426 #define rwlock_unlock_write(m) _rwlock_unlock_write_nodebug(m)
427 #define rwlock_assert_reading(m) do { } while (0)
428 #define rwlock_assert_writing(m) do { } while (0)
429 #define rwlock_assert_locked(m) do { } while (0)
430 #define rwlock_assert_unlocked(m) do { } while (0)
434 struct _objc_lock_list
;
435 extern void _destroyLockList(struct _objc_lock_list
*locks
);
437 extern int _mutex_lock_debug(mutex_t
*lock
, const char *name
);
438 extern int _mutex_try_lock_debug(mutex_t
*lock
, const char *name
);
439 extern int _mutex_unlock_debug(mutex_t
*lock
, const char *name
);
440 extern void _mutex_assert_locked_debug(mutex_t
*lock
, const char *name
);
441 extern void _mutex_assert_unlocked_debug(mutex_t
*lock
, const char *name
);
443 extern int _recursive_mutex_lock_debug(recursive_mutex_t
*lock
, const char *name
);
444 extern int _recursive_mutex_try_lock_debug(recursive_mutex_t
*lock
, const char *name
);
445 extern int _recursive_mutex_unlock_debug(recursive_mutex_t
*lock
, const char *name
);
446 extern void _recursive_mutex_assert_locked_debug(recursive_mutex_t
*lock
, const char *name
);
447 extern void _recursive_mutex_assert_unlocked_debug(recursive_mutex_t
*lock
, const char *name
);
449 extern int _monitor_enter_debug(monitor_t
*lock
, const char *name
);
450 extern int _monitor_exit_debug(monitor_t
*lock
, const char *name
);
451 extern int _monitor_wait_debug(monitor_t
*lock
, const char *name
);
452 extern void _monitor_assert_locked_debug(monitor_t
*lock
, const char *name
);
453 extern void _monitor_assert_unlocked_debug(monitor_t
*lock
, const char *name
);
455 extern void _rwlock_read_debug(rwlock_t
*l
, const char *name
);
456 extern void _rwlock_write_debug(rwlock_t
*l
, const char *name
);
457 extern int _rwlock_try_read_debug(rwlock_t
*l
, const char *name
);
458 extern int _rwlock_try_write_debug(rwlock_t
*l
, const char *name
);
459 extern void _rwlock_unlock_read_debug(rwlock_t
*l
, const char *name
);
460 extern void _rwlock_unlock_write_debug(rwlock_t
*l
, const char *name
);
461 extern void _rwlock_assert_reading_debug(rwlock_t
*l
, const char *name
);
462 extern void _rwlock_assert_writing_debug(rwlock_t
*l
, const char *name
);
463 extern void _rwlock_assert_locked_debug(rwlock_t
*l
, const char *name
);
464 extern void _rwlock_assert_unlocked_debug(rwlock_t
*l
, const char *name
);
466 #define mutex_lock(m) _mutex_lock_debug (m, #m)
467 #define mutex_try_lock(m) _mutex_try_lock_debug (m, #m)
468 #define mutex_unlock(m) _mutex_unlock_debug (m, #m)
469 #define mutex_assert_locked(m) _mutex_assert_locked_debug (m, #m)
470 #define mutex_assert_unlocked(m) _mutex_assert_unlocked_debug (m, #m)
472 #define recursive_mutex_lock(m) _recursive_mutex_lock_debug (m, #m)
473 #define recursive_mutex_try_lock(m) _recursive_mutex_try_lock_debug (m, #m)
474 #define recursive_mutex_unlock(m) _recursive_mutex_unlock_debug (m, #m)
475 #define recursive_mutex_assert_locked(m) _recursive_mutex_assert_locked_debug (m, #m)
476 #define recursive_mutex_assert_unlocked(m) _recursive_mutex_assert_unlocked_debug (m, #m)
478 #define monitor_enter(m) _monitor_enter_debug(m, #m)
479 #define monitor_exit(m) _monitor_exit_debug(m, #m)
480 #define monitor_wait(m) _monitor_wait_debug(m, #m)
481 #define monitor_assert_locked(m) _monitor_assert_locked_debug(m, #m)
482 #define monitor_assert_unlocked(m) _monitor_assert_unlocked_debug(m, #m)
484 #define rwlock_read(m) _rwlock_read_debug(m, #m)
485 #define rwlock_write(m) _rwlock_write_debug(m, #m)
486 #define rwlock_try_read(m) _rwlock_try_read_debug(m, #m)
487 #define rwlock_try_write(m) _rwlock_try_write_debug(m, #m)
488 #define rwlock_unlock_read(m) _rwlock_unlock_read_debug(m, #m)
489 #define rwlock_unlock_write(m) _rwlock_unlock_write_debug(m, #m)
490 #define rwlock_assert_reading(m) _rwlock_assert_reading_debug(m, #m)
491 #define rwlock_assert_writing(m) _rwlock_assert_writing_debug(m, #m)
492 #define rwlock_assert_locked(m) _rwlock_assert_locked_debug(m, #m)
493 #define rwlock_assert_unlocked(m) _rwlock_assert_unlocked_debug(m, #m)
497 #define rwlock_unlock(m, s) \
499 if ((s) == RDONLY) rwlock_unlock_read(m); \
500 else if ((s) == RDWR) rwlock_unlock_write(m); \
504 extern NXHashTable
*class_hash
;
507 /* nil handler object */
508 extern id _objc_nilReceiver
;
509 extern id
_objc_setNilReceiver(id newNilReceiver
);
510 extern id
_objc_getNilReceiver(void);
513 /* forward handler functions */
514 extern void *_objc_forward_handler
;
515 extern void *_objc_forward_stret_handler
;
517 /* GC and RTP startup */
518 extern void gc_init(BOOL on
);
519 extern void rtp_init(void);
522 struct alt_handler_list
;
523 extern void exception_init(void);
524 extern void _destroyAltHandlerList(struct alt_handler_list
*list
);
526 /* Class change notifications (gdb only for now) */
527 #define OBJC_CLASS_ADDED (1<<0)
528 #define OBJC_CLASS_REMOVED (1<<1)
529 #define OBJC_CLASS_IVARS_CHANGED (1<<2)
530 #define OBJC_CLASS_METHODS_CHANGED (1<<3)
531 extern void gdb_objc_class_changed(Class cls
, unsigned long changes
, const char *classname
)
532 __attribute__((noinline
));
534 /* Write barrier implementations */
535 extern id
objc_assign_strongCast_non_gc(id value
, id
*dest
);
536 extern id
objc_assign_global_non_gc(id value
, id
*dest
);
537 extern id
objc_assign_ivar_non_gc(id value
, id dest
, ptrdiff_t offset
);
538 extern id
objc_assign_strongCast_gc(id val
, id
*dest
);
539 extern id
objc_assign_global_gc(id val
, id
*dest
);
540 extern id
objc_assign_ivar_gc(id value
, id dest
, ptrdiff_t offset
);
544 /* GC weak reference fixup. */
545 extern void gc_fixup_weakreferences(id newObject
, id oldObject
);
547 /* GC datasegment registration. */
548 extern void gc_register_datasegment(uintptr_t base
, size_t size
);
549 extern void gc_unregister_datasegment(uintptr_t base
, size_t size
);
552 objc_assign_ivar, objc_assign_global, and objc_assign_strongCast MUST NOT be called directly
553 from inside libobjc. They live in the data segment, and must be called through the
554 following pointer(s) for libobjc to exist in the shared cache.
556 Note: If we build with GC enabled, gcc will emit calls to the original functions, which will break this.
559 extern id (*objc_assign_ivar_internal
)(id
, id
, ptrdiff_t);
563 /* Code modification */
564 extern size_t objc_branch_size(void *entry
, void *target
);
565 extern size_t objc_write_branch(void *entry
, void *target
);
566 extern size_t objc_cond_branch_size(void *entry
, void *target
, unsigned cond
);
567 extern size_t objc_write_cond_branch(void *entry
, void *target
, unsigned cond
);
568 #if defined(__ppc__) || defined(__ppc64__)
569 #define COND_ALWAYS 0x02800000 /* BO=10100, BI=00000 */
570 #define COND_NE 0x00820000 /* BO=00100, BI=00010 */
571 #elif defined(__i386__) || defined(__x86_64__)
572 #define COND_ALWAYS 0xE9 /* JMP rel32 */
573 #define COND_NE 0x85 /* JNE rel32 (0F 85) */
577 /* Thread-safe info field */
579 extern void _class_setInfo(Class cls
, long set
);
580 extern void _class_clearInfo(Class cls
, long clear
);
581 extern void _class_changeInfo(Class cls
, long set
, long clear
);
585 #if !defined(SEG_OBJC)
586 #define SEG_OBJC "__OBJC" /* objective-C runtime segment */
590 // Settings from environment variables
592 # define ENV(x) enum { x = 0 }
594 # define ENV(x) extern int x
596 ENV(PrintImages
); // env OBJC_PRINT_IMAGES
597 ENV(PrintLoading
); // env OBJC_PRINT_LOAD_METHODS
598 ENV(PrintInitializing
); // env OBJC_PRINT_INITIALIZE_METHODS
599 ENV(PrintResolving
); // env OBJC_PRINT_RESOLVED_METHODS
600 ENV(PrintConnecting
); // env OBJC_PRINT_CLASS_SETUP
601 ENV(PrintProtocols
); // env OBJC_PRINT_PROTOCOL_SETUP
602 ENV(PrintIvars
); // env OBJC_PRINT_IVAR_SETUP
603 ENV(PrintVtables
); // env OBJC_PRINT_VTABLE_SETUP
604 ENV(PrintVtableImages
); // env OBJC_PRINT_VTABLE_IMAGES
605 ENV(PrintFuture
); // env OBJC_PRINT_FUTURE_CLASSES
606 ENV(PrintRTP
); // env OBJC_PRINT_RTP
607 ENV(PrintGC
); // env OBJC_PRINT_GC
608 ENV(PrintPreopt
); // env OBJC_PRINT_PREOPTIMIZATION
609 ENV(PrintCxxCtors
); // env OBJC_PRINT_CXX_CTORS
610 ENV(PrintExceptions
); // env OBJC_PRINT_EXCEPTIONS
611 ENV(PrintAltHandlers
); // env OBJC_PRINT_ALT_HANDLERS
612 ENV(PrintDeprecation
); // env OBJC_PRINT_DEPRECATION_WARNINGS
613 ENV(PrintReplacedMethods
); // env OBJC_PRINT_REPLACED_METHODS
614 ENV(PrintCaches
); // env OBJC_PRINT_CACHE_SETUP
615 ENV(UseInternalZone
); // env OBJC_USE_INTERNAL_ZONE
617 ENV(DebugUnload
); // env OBJC_DEBUG_UNLOAD
618 ENV(DebugFragileSuperclasses
); // env OBJC_DEBUG_FRAGILE_SUPERCLASSES
619 ENV(DebugFinalizers
); // env OBJC_DEBUG_FINALIZERS
620 ENV(DebugNilSync
); // env OBJC_DEBUG_NIL_SYNC
622 ENV(DisableGC
); // env OBJC_DISABLE_GC
623 ENV(DisableVtables
); // env OBJC_DISABLE_VTABLES
624 ENV(DisablePreopt
); // env OBJC_DISABLE_PREOPTIMIZATION
627 extern void environ_init(void);
629 extern void logReplacedMethod(const char *className
, SEL s
, BOOL isMeta
, const char *catName
, IMP oldImp
, IMP newImp
);
632 static __inline
int _objc_strcmp(const char *s1
, const char *s2
) {
634 for ( ; (c1
= *s1
) == (c2
= *s2
); s1
++, s2
++)
640 static __inline
uint32_t _objc_strhash(const char *s
) {
645 hash
+= (hash
<< 8) + a
;
651 // objc per-thread storage
653 struct _objc_initializing_classes
*initializingClasses
; // for +initialize
654 struct _objc_lock_list
*lockList
; // for lock debugging
655 struct SyncCache
*syncCache
; // for @synchronize
656 struct alt_handler_list
*handlerList
; // for exception alt handlers
658 // If you add new fields here, don't forget to update
659 // _objc_pthread_destroyspecific()
661 } _objc_pthread_data
;
663 extern _objc_pthread_data
*_objc_fetch_pthread_data(BOOL create
);
664 extern void tls_init(void);
669 #define ISCLASS(cls) (((cls)->info & CLS_CLASS) != 0)
670 #define ISMETA(cls) (((cls)->info & CLS_META) != 0)
671 #define GETMETA(cls) (ISMETA(cls) ? (cls) : (cls)->isa)
675 // Attribute for global variables to keep them out of bss storage
676 // To save one page per non-Objective-C process, variables used in
677 // the "Objective-C not used" case should not be in bss storage.
678 // On Tiger, this reduces the number of touched pages for each
679 // CoreFoundation-only process from three to two. See #3857126 and #3857136.
680 #define NOBSS __attribute__((section("__DATA,__data")))
686 static inline int isPowerOf2(unsigned long l
) { return 1 == __builtin_popcountl(l
); }
688 extern void flush_caches(Class cls
, BOOL flush_meta
);
689 extern void flush_cache(Class cls
);
690 extern BOOL
_cache_fill(Class cls
, Method smt
, SEL sel
);
691 extern void _cache_addForwardEntry(Class cls
, SEL sel
);
692 extern void _cache_free(Cache cache
);
694 extern mutex_t cacheUpdateLock
;
697 // used by flush_caches outside objc-cache.m
698 extern void _cache_flush(Class cls
);
699 #ifdef OBJC_INSTRUMENTED
700 extern unsigned int LinearFlushCachesCount
;
701 extern unsigned int LinearFlushCachesVisitedCount
;
702 extern unsigned int MaxLinearFlushCachesVisitedCount
;
703 extern unsigned int NonlinearFlushCachesCount
;
704 extern unsigned int NonlinearFlushCachesClassCount
;
705 extern unsigned int NonlinearFlushCachesVisitedCount
;
706 extern unsigned int MaxNonlinearFlushCachesVisitedCount
;
707 extern unsigned int IdealFlushCachesCount
;
708 extern unsigned int MaxIdealFlushCachesCount
;
714 BOOL
_objc_dumpHeap(auto_zone_t
*zone
, const char *filename
);
718 extern unsigned int encoding_getNumberOfArguments(const char *typedesc
);
719 extern unsigned int encoding_getSizeOfArguments(const char *typedesc
);
720 extern unsigned int encoding_getArgumentInfo(const char *typedesc
, int arg
, const char **type
, int *offset
);
721 extern void encoding_getReturnType(const char *t
, char *dst
, size_t dst_len
);
722 extern char * encoding_copyReturnType(const char *t
);
723 extern void encoding_getArgumentType(const char *t
, unsigned int index
, char *dst
, size_t dst_len
);
724 extern char *encoding_copyArgumentType(const char *t
, unsigned int index
);
727 extern void _destroySyncCache(struct SyncCache
*cache
);
733 size_t bitsAllocated
;
736 extern layout_bitmap
layout_bitmap_create(const unsigned char *layout_string
, size_t layoutStringInstanceSize
, size_t instanceSize
, BOOL weak
);
737 extern void layout_bitmap_free(layout_bitmap bits
);
738 extern const unsigned char *layout_string_create(layout_bitmap bits
);
739 extern void layout_bitmap_set_ivar(layout_bitmap bits
, const char *type
, size_t offset
);
740 extern void layout_bitmap_grow(layout_bitmap
*bits
, size_t newCount
);
741 extern void layout_bitmap_slide(layout_bitmap
*bits
, size_t oldPos
, size_t newPos
);
742 extern BOOL
layout_bitmap_splat(layout_bitmap dst
, layout_bitmap src
,
743 size_t oldSrcInstanceSize
);
744 extern BOOL
layout_bitmap_or(layout_bitmap dst
, layout_bitmap src
, const char *msg
);
745 extern BOOL
layout_bitmap_clear(layout_bitmap dst
, layout_bitmap src
, const char *msg
);
746 extern void layout_bitmap_print(layout_bitmap bits
);
750 extern id
look_up_class(const char *aClassName
, BOOL includeUnconnected
, BOOL includeClassHandler
);
751 extern const char *map_images(enum dyld_image_states state
, uint32_t infoCount
, const struct dyld_image_info infoList
[]);
752 extern const char *map_images_nolock(enum dyld_image_states state
, uint32_t infoCount
, const struct dyld_image_info infoList
[]);
753 extern const char * load_images(enum dyld_image_states state
, uint32_t infoCount
, const struct dyld_image_info infoList
[]);
754 extern BOOL
load_images_nolock(enum dyld_image_states state
, uint32_t infoCount
, const struct dyld_image_info infoList
[]);
755 extern void unmap_image(const struct mach_header
*mh
, intptr_t vmaddr_slide
);
756 extern void unmap_image_nolock(const struct mach_header
*mh
, intptr_t vmaddr_slide
);
757 extern void _read_images(header_info
**hList
, uint32_t hCount
);
758 extern void prepare_load_methods(header_info
*hi
);
759 extern void _unload_image(header_info
*hi
);
760 extern const char ** _objc_copyClassNamesForImage(header_info
*hi
, unsigned int *outCount
);
762 extern Class
_objc_allocateFutureClass(const char *name
);
765 extern Property
*copyPropertyList(struct objc_property_list
*plist
, unsigned int *outCount
);
768 extern const header_info
*_headerForClass(Class cls
);
771 extern Property
property_list_nth(const struct objc_property_list
*plist
, uint32_t i
);
772 extern size_t property_list_size(const struct objc_property_list
*plist
);
774 extern Class
_class_getSuperclass(Class cls
);
775 extern BOOL
_class_getInfo(Class cls
, int info
);
776 extern const char *_class_getName(Class cls
);
777 extern size_t _class_getInstanceSize(Class cls
);
778 extern Class
_class_getMeta(Class cls
);
779 extern BOOL
_class_isMetaClass(Class cls
);
780 extern Cache
_class_getCache(Class cls
);
781 extern void _class_setCache(Class cls
, Cache cache
);
782 extern BOOL
_class_isInitializing(Class cls
);
783 extern BOOL
_class_isInitialized(Class cls
);
784 extern void _class_setInitializing(Class cls
);
785 extern void _class_setInitialized(Class cls
);
786 extern Class
_class_getNonMetaClass(Class cls
);
787 extern Method
_class_getMethod(Class cls
, SEL sel
);
788 extern Method
_class_getMethodNoSuper(Class cls
, SEL sel
);
789 extern Method
_class_getMethodNoSuper_nolock(Class cls
, SEL sel
);
790 extern BOOL
_class_isLoadable(Class cls
);
791 extern IMP
_class_getLoadMethod(Class cls
);
792 extern BOOL
_class_hasLoadMethod(Class cls
);
793 extern BOOL
_class_hasCxxStructorsNoSuper(Class cls
);
794 extern BOOL
_class_shouldFinalizeOnMainThread(Class cls
);
795 extern void _class_setFinalizeOnMainThread(Class cls
);
796 extern BOOL
_class_instancesHaveAssociatedObjects(Class cls
);
797 extern void _class_assertInstancesHaveAssociatedObjects(Class cls
);
798 extern BOOL
_class_shouldGrowCache(Class cls
);
799 extern void _class_setGrowCache(Class cls
, BOOL grow
);
800 extern Ivar
_class_getVariable(Class cls
, const char *name
);
802 extern id
_internal_class_createInstanceFromZone(Class cls
, size_t extraBytes
,
804 extern id
_internal_object_dispose(id anObject
);
806 extern Class
gdb_class_getClass(Class cls
);
807 extern BOOL
class_instancesHaveAssociatedObjects(Class cls
);
808 OBJC_EXPORT BOOL
gdb_objc_isRuntimeLocked();
810 extern const char *_category_getName(Category cat
);
811 extern const char *_category_getClassName(Category cat
);
812 extern Class
_category_getClass(Category cat
);
813 extern IMP
_category_getLoadMethod(Category cat
);
816 #define oldcls(cls) ((struct old_class *)cls)
817 #define oldprotocol(proto) ((struct old_protocol *)proto)
818 #define oldmethod(meth) ((struct old_method *)meth)
819 #define oldcategory(cat) ((struct old_category *)cat)
820 #define oldivar(ivar) ((struct old_ivar *)ivar)
822 static inline struct old_method
*_method_asOld(Method m
) { return (struct old_method
*)m
; }
823 static inline struct old_class
*_class_asOld(Class cls
) { return (struct old_class
*)cls
; }
824 static inline struct old_category
*_category_asOld(Category cat
) { return (struct old_category
*)cat
; }
826 extern void unload_class(struct old_class
*cls
);
827 Class
_class_getNonexistentObjectClass(void);
830 extern BOOL
object_cxxConstruct(id obj
);
831 extern void object_cxxDestruct(id obj
);
833 extern Method
_class_resolveMethod(Class cls
, SEL sel
);
834 extern void log_and_fill_cache(Class cls
, Class implementer
, Method meth
, SEL sel
);
837 #define CLS_CLASS 0x1
839 #define CLS_INITIALIZED 0x4
840 #define CLS_POSING 0x8
841 #define CLS_MAPPED 0x10
842 #define CLS_FLUSH_CACHE 0x20
843 #define CLS_GROW_CACHE 0x40
844 #define CLS_NEED_BIND 0x80
845 #define CLS_METHOD_ARRAY 0x100
846 // the JavaBridge constructs classes with these markers
847 #define CLS_JAVA_HYBRID 0x200
848 #define CLS_JAVA_CLASS 0x400
849 // thread-safe +initialize
850 #define CLS_INITIALIZING 0x800
852 #define CLS_FROM_BUNDLE 0x1000
854 #define CLS_HAS_CXX_STRUCTORS 0x2000
855 // Lazy method list arrays
856 #define CLS_NO_METHOD_ARRAY 0x4000
857 // +load implementation
858 #define CLS_HAS_LOAD_METHOD 0x8000
859 // objc_allocateClassPair API
860 #define CLS_CONSTRUCTING 0x10000
862 #define CLS_HIDDEN 0x20000
863 // GC: class has unsafe finalize method
864 #define CLS_FINALIZE_ON_MAIN_THREAD 0x40000
865 // Lazy property list arrays
866 #define CLS_NO_PROPERTY_ARRAY 0x80000
867 // +load implementation
868 #define CLS_CONNECTED 0x100000
869 #define CLS_LOADED 0x200000
870 // objc_allocateClassPair API
871 #define CLS_CONSTRUCTED 0x400000
872 // class is leaf for cache flushing
873 #define CLS_LEAF 0x800000
874 // class instances may have associative references
875 #define CLS_INSTANCES_HAVE_ASSOCIATED_OBJECTS 0x1000000
878 #define OBJC_WARN_DEPRECATED \
880 static int warned = 0; \
883 _objc_warn_deprecated(__FUNCTION__, NULL); \
889 #endif /* _OBJC_PRIVATE_H_ */