2 * Copyright (c) 2009 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 #ifndef _OBJC_INTERNAL_H
26 #define _OBJC_INTERNAL_H
29 * WARNING DANGER HAZARD BEWARE EEK
31 * Everything in this file is for Apple Internal use only.
32 * These will change in arbitrary OS updates and in unpredictable ways.
33 * When your program breaks, you get to keep both pieces.
37 * objc-internal.h: Private SPI for use by other system frameworks.
40 #include <objc/objc.h>
41 #include <objc/runtime.h>
42 #include <Availability.h>
43 #include <malloc/malloc.h>
44 #include <mach-o/loader.h>
45 #include <dispatch/dispatch.h>
47 // Include NSObject.h only if we're ObjC. Module imports get unhappy
50 #include <objc/NSObject.h>
53 // Termination reasons in the OS_REASON_OBJC namespace.
54 #define OBJC_EXIT_REASON_UNSPECIFIED 1
55 #define OBJC_EXIT_REASON_GC_NOT_SUPPORTED 2
57 // This is the allocation size required for each of the class and the metaclass
58 // with objc_initializeClassPair() and objc_readClassPair().
59 // The runtime's class structure will never grow beyond this.
60 #define OBJC_MAX_CLASS_SIZE (32*sizeof(void*))
62 // Private objc_setAssociatedObject policy modifier. When an object is
63 // destroyed, associated objects attached to that object that are marked with
64 // this will be released after all associated objects not so marked.
66 // In addition, such associations are not removed when calling
67 // objc_removeAssociatedObjects.
69 // NOTE: This should be used sparingly. Performance will be poor when a single
70 // object has more than a few (deliberately vague) associated objects marked
71 // with this flag. If you're not sure if you should use this, you should not use
73 #define _OBJC_ASSOCIATION_SYSTEM_OBJECT (1 << 16)
77 // This symbol is exported only from debug builds of libobjc itself.
78 #if defined(OBJC_IS_DEBUG_BUILD)
79 OBJC_EXPORT
void _objc_isDebugBuild(void);
82 // In-place construction of an Objective-C class.
83 // cls and metacls must each be OBJC_MAX_CLASS_SIZE bytes.
84 // Returns nil if a class with the same name already exists.
85 // Returns nil if the superclass is under construction.
86 // Call objc_registerClassPair() when you are done.
87 OBJC_EXPORT Class _Nullable
88 objc_initializeClassPair(Class _Nullable superclass
, const char * _Nonnull name
,
89 Class _Nonnull cls
, Class _Nonnull metacls
)
90 OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0, 2.0);
92 // Class and metaclass construction from a compiler-generated memory image.
93 // cls and cls->isa must each be OBJC_MAX_CLASS_SIZE bytes.
94 // Extra bytes not used the the metadata must be zero.
95 // info is the same objc_image_info that would be emitted by a static compiler.
96 // Returns nil if a class with the same name already exists.
97 // Returns nil if the superclass is nil and the class is not marked as a root.
98 // Returns nil if the superclass is under construction.
99 // Do not call objc_registerClassPair().
101 struct objc_image_info
;
102 OBJC_EXPORT Class _Nullable
103 objc_readClassPair(Class _Nonnull cls
,
104 const struct objc_image_info
* _Nonnull info
)
105 OBJC_AVAILABLE(10.10, 8.0, 9.0, 1.0, 2.0);
108 // Batch object allocation using malloc_zone_batch_malloc().
110 class_createInstances(Class _Nullable cls
, size_t extraBytes
,
111 id _Nonnull
* _Nonnull results
, unsigned num_requested
)
112 OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0)
113 OBJC_ARC_UNAVAILABLE
;
115 // Get the isa pointer written into objects just before being freed.
116 OBJC_EXPORT Class _Nonnull
117 _objc_getFreedObjectClass(void)
118 OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
120 // env NSObjCMessageLoggingEnabled
122 instrumentObjcMessageSends(BOOL flag
)
123 OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
125 // Initializer called by libSystem
129 OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0, 2.0);
131 OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0);
134 // fork() safety called by libSystem
136 _objc_atfork_prepare(void)
137 OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0);
140 _objc_atfork_parent(void)
141 OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0);
144 _objc_atfork_child(void)
145 OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0);
147 // Return YES if GC is on and `object` is a GC allocation.
149 objc_isAuto(id _Nullable object
)
150 OBJC_OSX_DEPRECATED_OTHERS_UNAVAILABLE(10.4, 10.8, "it always returns NO");
154 objc_dumpHeap(char * _Nonnull filename
, unsigned long length
)
155 OBJC_OSX_DEPRECATED_OTHERS_UNAVAILABLE(10.4, 10.8, "it always returns NO");
157 // GC startup callback from Foundation
158 OBJC_EXPORT malloc_zone_t
* _Nullable
159 objc_collect_init(int (* _Nonnull callback
)(void))
160 OBJC_OSX_DEPRECATED_OTHERS_UNAVAILABLE(10.4, 10.8, "it does nothing");
163 // Copies the list of currently realized classes
164 // intended for introspection only
165 // most users will want objc_copyClassList instead.
167 Class _Nonnull
* _Nullable
168 objc_copyRealizedClassList(unsigned int *_Nullable outCount
)
169 OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0);
171 typedef struct objc_imp_cache_entry
{
174 } objc_imp_cache_entry
;
177 objc_imp_cache_entry
*_Nullable
178 class_copyImpCache(Class _Nonnull cls
, int * _Nullable outCount
)
179 OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0);
183 sel_hash(SEL _Nullable sel
)
184 OBJC_AVAILABLE(10.16, 14.0, 14.0, 7.0, 6.0);
188 // Plainly-implemented GC barriers. Rosetta used to use these.
189 OBJC_EXPORT id _Nullable
190 objc_assign_strongCast_generic(id _Nullable value
, id _Nullable
* _Nonnull dest
)
191 UNAVAILABLE_ATTRIBUTE
;
193 OBJC_EXPORT id _Nullable
194 objc_assign_global_generic(id _Nullable value
, id _Nullable
* _Nonnull dest
)
195 UNAVAILABLE_ATTRIBUTE
;
197 OBJC_EXPORT id _Nullable
198 objc_assign_threadlocal_generic(id _Nullable value
,
199 id _Nullable
* _Nonnull dest
)
200 UNAVAILABLE_ATTRIBUTE
;
202 OBJC_EXPORT id _Nullable
203 objc_assign_ivar_generic(id _Nullable value
, id _Nonnull dest
, ptrdiff_t offset
)
204 UNAVAILABLE_ATTRIBUTE
;
206 // GC preflight for an app executable.
207 // 1: some slice requires GC
208 // 0: no slice requires GC
209 // -1: I/O or file format error
211 objc_appRequiresGC(int fd
)
212 __OSX_AVAILABLE(10.11)
213 __IOS_UNAVAILABLE __TVOS_UNAVAILABLE
214 __WATCHOS_UNAVAILABLE
215 #ifndef __APPLE_BLEACH_SDK__
216 __BRIDGEOS_UNAVAILABLE
220 // Install missing-class callback. Used by the late unlamented ZeroLink.
222 _objc_setClassLoader(BOOL (* _Nonnull newClassLoader
)(const char * _Nonnull
))
225 #if !(TARGET_OS_OSX && !TARGET_OS_MACCATALYST && __i386__)
226 // Add a class copy fixup handler. The name is a misnomer, as
227 // multiple calls will install multiple handlers. Older versions
228 // of the Swift runtime call it by name, and it's only used by Swift
229 // so it's not worth deprecating this name in favor of a better one.
231 _objc_setClassCopyFixupHandler(void (* _Nonnull newFixupHandler
)
232 (Class _Nonnull oldClass
, Class _Nonnull newClass
))
233 OBJC_AVAILABLE(10.14, 12.0, 12.0, 5.0, 3.0);
236 // Install handler for allocation failures.
237 // Handler may abort, or throw, or provide an object to return.
239 _objc_setBadAllocHandler(id
_Nullable (* _Nonnull newHandler
)
240 (Class _Nullable isa
))
241 OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0, 2.0);
243 // Used by ExceptionHandling.framework
246 _objc_error(id _Nullable rcv
, const char * _Nonnull fmt
, va_list args
)
247 __attribute__((noreturn
, cold
))
248 OBJC_OSX_DEPRECATED_OTHERS_UNAVAILABLE(10.0, 10.5, "use other logging facilities instead");
254 * Returns the names of all the classes within a library.
256 * @param image The mach header for library or framework you are inquiring about.
257 * @param outCount The number of class names returned.
259 * @return An array of C strings representing the class names.
261 OBJC_EXPORT
const char * _Nonnull
* _Nullable
262 objc_copyClassNamesForImageHeader(const struct mach_header
* _Nonnull mh
,
263 unsigned int * _Nullable outCount
)
264 OBJC_AVAILABLE(10.14, 12.0, 12.0, 5.0, 3.0);
267 * Returns the all the classes within a library.
269 * @param image The mach header for library or framework you are inquiring about.
270 * @param outCount The number of class names returned.
272 * @return An array of Class objects
275 OBJC_EXPORT Class _Nonnull
* _Nullable
276 objc_copyClassesForImage(const char * _Nonnull image
,
277 unsigned int * _Nullable outCount
)
278 OBJC_AVAILABLE(10.16, 14.0, 14.0, 7.0, 4.0);
281 // Tagged pointer objects.
284 #define OBJC_HAVE_TAGGED_POINTERS 1
287 #if OBJC_HAVE_TAGGED_POINTERS
289 // Tagged pointer layout and usage is subject to change on different OS versions.
291 // Tag indexes 0..<7 have a 60-bit payload.
292 // Tag index 7 is reserved.
293 // Tag indexes 8..<264 have a 52-bit payload.
294 // Tag index 264 is reserved.
296 #if __has_feature(objc_fixed_enum) || __cplusplus >= 201103L
297 enum objc_tag_index_t
: uint16_t
299 typedef uint16_t objc_tag_index_t
;
306 OBJC_TAG_NSString
= 2,
307 OBJC_TAG_NSNumber
= 3,
308 OBJC_TAG_NSIndexPath
= 4,
309 OBJC_TAG_NSManagedObjectID
= 5,
313 OBJC_TAG_RESERVED_7
= 7,
316 OBJC_TAG_Photos_1
= 8,
317 OBJC_TAG_Photos_2
= 9,
318 OBJC_TAG_Photos_3
= 10,
319 OBJC_TAG_Photos_4
= 11,
324 OBJC_TAG_NSColor
= 16,
325 OBJC_TAG_UIColor
= 17,
326 OBJC_TAG_CGColor
= 18,
327 OBJC_TAG_NSIndexSet
= 19,
328 OBJC_TAG_NSMethodSignature
= 20,
329 OBJC_TAG_UTTypeRecord
= 21,
331 // When using the split tagged pointer representation
332 // (OBJC_SPLIT_TAGGED_POINTERS), this is the first tag where
333 // the tag and payload are unobfuscated. All tags from here to
334 // OBJC_TAG_Last52BitPayload are unobfuscated. The shared cache
335 // builder is able to construct these as long as the low bit is
336 // not set (i.e. even-numbered tags).
337 OBJC_TAG_FirstUnobfuscatedSplitTag
= 136, // 128 + 8, first ext tag with high bit set
339 OBJC_TAG_Constant_CFString
= 136,
341 OBJC_TAG_First60BitPayload
= 0,
342 OBJC_TAG_Last60BitPayload
= 6,
343 OBJC_TAG_First52BitPayload
= 8,
344 OBJC_TAG_Last52BitPayload
= 263,
346 OBJC_TAG_RESERVED_264
= 264
348 #if __has_feature(objc_fixed_enum) && !defined(__cplusplus)
349 typedef enum objc_tag_index_t objc_tag_index_t
;
353 // Returns true if tagged pointers are enabled.
354 // The other functions below must not be called if tagged pointers are disabled.
356 _objc_taggedPointersEnabled(void);
358 // Register a class for a tagged pointer tag.
359 // Aborts if the tag is invalid or already in use.
361 _objc_registerTaggedPointerClass(objc_tag_index_t tag
, Class _Nonnull cls
)
362 OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0);
364 // Returns the registered class for the given tag.
365 // Returns nil if the tag is valid but has no registered class.
366 // Aborts if the tag is invalid.
367 OBJC_EXPORT Class _Nullable
368 _objc_getClassForTag(objc_tag_index_t tag
)
369 OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0);
371 // Create a tagged pointer object with the given tag and payload.
372 // Assumes the tag is valid.
373 // Assumes tagged pointers are enabled.
374 // The payload will be silently truncated to fit.
375 static inline void * _Nonnull
376 _objc_makeTaggedPointer(objc_tag_index_t tag
, uintptr_t payload
);
378 // Return true if ptr is a tagged pointer object.
379 // Does not check the validity of ptr's class.
381 _objc_isTaggedPointer(const void * _Nullable ptr
);
383 // Extract the tag value from the given tagged pointer object.
384 // Assumes ptr is a valid tagged pointer object.
385 // Does not check the validity of ptr's tag.
386 static inline objc_tag_index_t
387 _objc_getTaggedPointerTag(const void * _Nullable ptr
);
389 // Extract the payload from the given tagged pointer object.
390 // Assumes ptr is a valid tagged pointer object.
391 // The payload value is zero-extended.
392 static inline uintptr_t
393 _objc_getTaggedPointerValue(const void * _Nullable ptr
);
395 // Extract the payload from the given tagged pointer object.
396 // Assumes ptr is a valid tagged pointer object.
397 // The payload value is sign-extended.
398 static inline intptr_t
399 _objc_getTaggedPointerSignedValue(const void * _Nullable ptr
);
401 // Don't use the values below. Use the declarations above.
404 // ARM64 uses a new tagged pointer scheme where normal tags are in
405 // the low bits, extended tags are in the high bits, and half of the
406 // extended tag space is reserved for unobfuscated payloads.
407 # define OBJC_SPLIT_TAGGED_POINTERS 1
409 # define OBJC_SPLIT_TAGGED_POINTERS 0
412 #if (TARGET_OS_OSX || TARGET_OS_MACCATALYST) && __x86_64__
413 // 64-bit Mac - tag bit is LSB
414 # define OBJC_MSB_TAGGED_POINTERS 0
416 // Everything else - tag bit is MSB
417 # define OBJC_MSB_TAGGED_POINTERS 1
420 #define _OBJC_TAG_INDEX_MASK 0x7UL
422 #if OBJC_SPLIT_TAGGED_POINTERS
423 #define _OBJC_TAG_SLOT_COUNT 8
424 #define _OBJC_TAG_SLOT_MASK 0x7UL
426 // array slot includes the tag bit itself
427 #define _OBJC_TAG_SLOT_COUNT 16
428 #define _OBJC_TAG_SLOT_MASK 0xfUL
431 #define _OBJC_TAG_EXT_INDEX_MASK 0xff
432 // array slot has no extra bits
433 #define _OBJC_TAG_EXT_SLOT_COUNT 256
434 #define _OBJC_TAG_EXT_SLOT_MASK 0xff
436 #if OBJC_SPLIT_TAGGED_POINTERS
437 # define _OBJC_TAG_MASK (1UL<<63)
438 # define _OBJC_TAG_INDEX_SHIFT 0
439 # define _OBJC_TAG_SLOT_SHIFT 0
440 # define _OBJC_TAG_PAYLOAD_LSHIFT 1
441 # define _OBJC_TAG_PAYLOAD_RSHIFT 4
442 # define _OBJC_TAG_EXT_MASK (_OBJC_TAG_MASK | 0x7UL)
443 # define _OBJC_TAG_NO_OBFUSCATION_MASK ((1UL<<62) | _OBJC_TAG_EXT_MASK)
444 # define _OBJC_TAG_CONSTANT_POINTER_MASK \
445 ~(_OBJC_TAG_EXT_MASK | ((uintptr_t)_OBJC_TAG_EXT_SLOT_MASK << _OBJC_TAG_EXT_SLOT_SHIFT))
446 # define _OBJC_TAG_EXT_INDEX_SHIFT 55
447 # define _OBJC_TAG_EXT_SLOT_SHIFT 55
448 # define _OBJC_TAG_EXT_PAYLOAD_LSHIFT 9
449 # define _OBJC_TAG_EXT_PAYLOAD_RSHIFT 12
450 #elif OBJC_MSB_TAGGED_POINTERS
451 # define _OBJC_TAG_MASK (1UL<<63)
452 # define _OBJC_TAG_INDEX_SHIFT 60
453 # define _OBJC_TAG_SLOT_SHIFT 60
454 # define _OBJC_TAG_PAYLOAD_LSHIFT 4
455 # define _OBJC_TAG_PAYLOAD_RSHIFT 4
456 # define _OBJC_TAG_EXT_MASK (0xfUL<<60)
457 # define _OBJC_TAG_EXT_INDEX_SHIFT 52
458 # define _OBJC_TAG_EXT_SLOT_SHIFT 52
459 # define _OBJC_TAG_EXT_PAYLOAD_LSHIFT 12
460 # define _OBJC_TAG_EXT_PAYLOAD_RSHIFT 12
462 # define _OBJC_TAG_MASK 1UL
463 # define _OBJC_TAG_INDEX_SHIFT 1
464 # define _OBJC_TAG_SLOT_SHIFT 0
465 # define _OBJC_TAG_PAYLOAD_LSHIFT 0
466 # define _OBJC_TAG_PAYLOAD_RSHIFT 4
467 # define _OBJC_TAG_EXT_MASK 0xfUL
468 # define _OBJC_TAG_EXT_INDEX_SHIFT 4
469 # define _OBJC_TAG_EXT_SLOT_SHIFT 4
470 # define _OBJC_TAG_EXT_PAYLOAD_LSHIFT 0
471 # define _OBJC_TAG_EXT_PAYLOAD_RSHIFT 12
474 // Map of tags to obfuscated tags.
475 extern uintptr_t objc_debug_taggedpointer_obfuscator
;
477 #if OBJC_SPLIT_TAGGED_POINTERS
478 extern uint8_t objc_debug_tag60_permutations
[8];
480 static inline uintptr_t _objc_basicTagToObfuscatedTag(uintptr_t tag
) {
481 return objc_debug_tag60_permutations
[tag
];
484 static inline uintptr_t _objc_obfuscatedTagToBasicTag(uintptr_t tag
) {
485 for (unsigned i
= 0; i
< 7; i
++)
486 if (objc_debug_tag60_permutations
[i
] == tag
)
492 static inline void * _Nonnull
493 _objc_encodeTaggedPointer(uintptr_t ptr
)
495 uintptr_t value
= (objc_debug_taggedpointer_obfuscator
^ ptr
);
496 #if OBJC_SPLIT_TAGGED_POINTERS
497 if ((value
& _OBJC_TAG_NO_OBFUSCATION_MASK
) == _OBJC_TAG_NO_OBFUSCATION_MASK
)
499 uintptr_t basicTag
= (value
>> _OBJC_TAG_INDEX_SHIFT
) & _OBJC_TAG_INDEX_MASK
;
500 uintptr_t permutedTag
= _objc_basicTagToObfuscatedTag(basicTag
);
501 value
&= ~(_OBJC_TAG_INDEX_MASK
<< _OBJC_TAG_INDEX_SHIFT
);
502 value
|= permutedTag
<< _OBJC_TAG_INDEX_SHIFT
;
504 return (void *)value
;
507 static inline uintptr_t
508 _objc_decodeTaggedPointer_noPermute(const void * _Nullable ptr
)
510 uintptr_t value
= (uintptr_t)ptr
;
511 #if OBJC_SPLIT_TAGGED_POINTERS
512 if ((value
& _OBJC_TAG_NO_OBFUSCATION_MASK
) == _OBJC_TAG_NO_OBFUSCATION_MASK
)
515 return value
^ objc_debug_taggedpointer_obfuscator
;
518 static inline uintptr_t
519 _objc_decodeTaggedPointer(const void * _Nullable ptr
)
521 uintptr_t value
= _objc_decodeTaggedPointer_noPermute(ptr
);
522 #if OBJC_SPLIT_TAGGED_POINTERS
523 uintptr_t basicTag
= (value
>> _OBJC_TAG_INDEX_SHIFT
) & _OBJC_TAG_INDEX_MASK
;
525 value
&= ~(_OBJC_TAG_INDEX_MASK
<< _OBJC_TAG_INDEX_SHIFT
);
526 value
|= _objc_obfuscatedTagToBasicTag(basicTag
) << _OBJC_TAG_INDEX_SHIFT
;
532 _objc_taggedPointersEnabled(void)
534 extern uintptr_t objc_debug_taggedpointer_mask
;
535 return (objc_debug_taggedpointer_mask
!= 0);
538 static inline void * _Nonnull
539 _objc_makeTaggedPointer(objc_tag_index_t tag
, uintptr_t value
)
541 // PAYLOAD_LSHIFT and PAYLOAD_RSHIFT are the payload extraction shifts.
542 // They are reversed here for payload insertion.
544 // ASSERT(_objc_taggedPointersEnabled());
545 if (tag
<= OBJC_TAG_Last60BitPayload
) {
546 // ASSERT(((value << _OBJC_TAG_PAYLOAD_RSHIFT) >> _OBJC_TAG_PAYLOAD_LSHIFT) == value);
549 ((uintptr_t)tag
<< _OBJC_TAG_INDEX_SHIFT
) |
550 ((value
<< _OBJC_TAG_PAYLOAD_RSHIFT
) >> _OBJC_TAG_PAYLOAD_LSHIFT
));
551 return _objc_encodeTaggedPointer(result
);
553 // ASSERT(tag >= OBJC_TAG_First52BitPayload);
554 // ASSERT(tag <= OBJC_TAG_Last52BitPayload);
555 // ASSERT(((value << _OBJC_TAG_EXT_PAYLOAD_RSHIFT) >> _OBJC_TAG_EXT_PAYLOAD_LSHIFT) == value);
557 (_OBJC_TAG_EXT_MASK
|
558 ((uintptr_t)(tag
- OBJC_TAG_First52BitPayload
) << _OBJC_TAG_EXT_INDEX_SHIFT
) |
559 ((value
<< _OBJC_TAG_EXT_PAYLOAD_RSHIFT
) >> _OBJC_TAG_EXT_PAYLOAD_LSHIFT
));
560 return _objc_encodeTaggedPointer(result
);
565 _objc_isTaggedPointer(const void * _Nullable ptr
)
567 return ((uintptr_t)ptr
& _OBJC_TAG_MASK
) == _OBJC_TAG_MASK
;
571 _objc_isTaggedPointerOrNil(const void * _Nullable ptr
)
573 // this function is here so that clang can turn this into
574 // a comparison with NULL when this is appropriate
575 // it turns out it's not able to in many cases without this
576 return !ptr
|| ((uintptr_t)ptr
& _OBJC_TAG_MASK
) == _OBJC_TAG_MASK
;
579 static inline objc_tag_index_t
580 _objc_getTaggedPointerTag(const void * _Nullable ptr
)
582 // ASSERT(_objc_isTaggedPointer(ptr));
583 uintptr_t value
= _objc_decodeTaggedPointer(ptr
);
584 uintptr_t basicTag
= (value
>> _OBJC_TAG_INDEX_SHIFT
) & _OBJC_TAG_INDEX_MASK
;
585 uintptr_t extTag
= (value
>> _OBJC_TAG_EXT_INDEX_SHIFT
) & _OBJC_TAG_EXT_INDEX_MASK
;
586 if (basicTag
== _OBJC_TAG_INDEX_MASK
) {
587 return (objc_tag_index_t
)(extTag
+ OBJC_TAG_First52BitPayload
);
589 return (objc_tag_index_t
)basicTag
;
593 static inline uintptr_t
594 _objc_getTaggedPointerValue(const void * _Nullable ptr
)
596 // ASSERT(_objc_isTaggedPointer(ptr));
597 uintptr_t value
= _objc_decodeTaggedPointer_noPermute(ptr
);
598 uintptr_t basicTag
= (value
>> _OBJC_TAG_INDEX_SHIFT
) & _OBJC_TAG_INDEX_MASK
;
599 if (basicTag
== _OBJC_TAG_INDEX_MASK
) {
600 return (value
<< _OBJC_TAG_EXT_PAYLOAD_LSHIFT
) >> _OBJC_TAG_EXT_PAYLOAD_RSHIFT
;
602 return (value
<< _OBJC_TAG_PAYLOAD_LSHIFT
) >> _OBJC_TAG_PAYLOAD_RSHIFT
;
606 static inline intptr_t
607 _objc_getTaggedPointerSignedValue(const void * _Nullable ptr
)
609 // ASSERT(_objc_isTaggedPointer(ptr));
610 uintptr_t value
= _objc_decodeTaggedPointer_noPermute(ptr
);
611 uintptr_t basicTag
= (value
>> _OBJC_TAG_INDEX_SHIFT
) & _OBJC_TAG_INDEX_MASK
;
612 if (basicTag
== _OBJC_TAG_INDEX_MASK
) {
613 return ((intptr_t)value
<< _OBJC_TAG_EXT_PAYLOAD_LSHIFT
) >> _OBJC_TAG_EXT_PAYLOAD_RSHIFT
;
615 return ((intptr_t)value
<< _OBJC_TAG_PAYLOAD_LSHIFT
) >> _OBJC_TAG_PAYLOAD_RSHIFT
;
619 # if OBJC_SPLIT_TAGGED_POINTERS
620 static inline void * _Nullable
621 _objc_getTaggedPointerRawPointerValue(const void * _Nullable ptr
) {
622 return (void *)((uintptr_t)ptr
& _OBJC_TAG_CONSTANT_POINTER_MASK
);
626 // OBJC_HAVE_TAGGED_POINTERS
631 * Returns the method implementation of an object.
633 * @param obj An Objective-C object.
634 * @param name An Objective-C selector.
636 * @return The IMP corresponding to the instance method implemented by
637 * the class of \e obj.
639 * @note Equivalent to:
641 * class_getMethodImplementation(object_getClass(obj), name);
643 OBJC_EXPORT IMP _Nonnull
644 object_getMethodImplementation(id _Nullable obj
, SEL _Nonnull name
)
645 OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0);
647 OBJC_EXPORT IMP _Nonnull
648 object_getMethodImplementation_stret(id _Nullable obj
, SEL _Nonnull name
)
649 OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0)
650 OBJC_ARM64_UNAVAILABLE
;
654 * Adds multiple methods to a class in bulk. This amortizes overhead that can be
655 * expensive when adding methods one by one with class_addMethod.
657 * @param cls The class to which to add the methods.
658 * @param names An array of selectors for the methods to add.
659 * @param imps An array of functions which implement the new methods.
660 * @param types An array of strings that describe the types of each method's
662 * @param count The number of items in the names, imps, and types arrays.
663 * @param outFiledCount Upon return, contains the number of failed selectors in
664 * the returned array.
666 * @return A NULL-terminated C array of selectors which could not be added. A
667 * method cannot be added when a method of that name already exists on that
668 * class. When no failures occur, the return value is \c NULL. When a non-NULL
669 * value is returned, the caller must free the array with \c free().
673 OBJC_EXPORT _Nullable SEL
* _Nullable
674 class_addMethodsBulk(_Nullable Class cls
, _Nonnull
const SEL
* _Nonnull names
,
675 _Nonnull
const IMP
* _Nonnull imps
,
676 const char * _Nonnull
* _Nonnull types
, uint32_t count
,
677 uint32_t * _Nullable outFailedCount
)
678 OBJC_AVAILABLE(10.14, 12.0, 12.0, 5.0, 3.0);
682 * Replaces multiple methods in a class in bulk. This amortizes overhead that
683 * can be expensive when adding methods one by one with class_replaceMethod.
685 * @param cls The class to modify.
686 * @param names An array of selectors for the methods to replace.
687 * @param imps An array of functions will be the new method implementantations.
688 * @param types An array of strings that describe the types of each method's
690 * @param count The number of items in the names, imps, and types arrays.
694 class_replaceMethodsBulk(_Nullable Class cls
,
695 _Nonnull
const SEL
* _Nonnull names
,
696 _Nonnull
const IMP
* _Nonnull imps
,
697 const char * _Nonnull
* _Nonnull types
,
699 OBJC_AVAILABLE(10.14, 12.0, 12.0, 5.0, 3.0);
703 // Instance-specific instance variable layout. This is no longer implemented.
706 _class_setIvarLayoutAccessor(Class _Nullable cls
,
707 const uint8_t* _Nullable (* _Nonnull accessor
)
708 (id _Nullable object
))
709 UNAVAILABLE_ATTRIBUTE
;
711 OBJC_EXPORT
const uint8_t * _Nullable
712 _object_getIvarLayout(Class _Nullable cls
, id _Nullable object
)
713 UNAVAILABLE_ATTRIBUTE
;
717 "Unknown" includes non-object ivars and non-ARC non-__weak ivars
718 "Strong" includes ARC __strong ivars
719 "Weak" includes ARC and new MRC __weak ivars
720 "Unretained" includes ARC __unsafe_unretained and old GC+MRC __weak ivars
723 objc_ivar_memoryUnknown
, // unknown / unknown
724 objc_ivar_memoryStrong
, // direct access / objc_storeStrong
725 objc_ivar_memoryWeak
, // objc_loadWeak[Retained] / objc_storeWeak
726 objc_ivar_memoryUnretained
// direct access / direct access
727 } objc_ivar_memory_management_t
;
729 OBJC_EXPORT objc_ivar_memory_management_t
730 _class_getIvarMemoryManagement(Class _Nullable cls
, Ivar _Nonnull ivar
)
731 OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0);
733 OBJC_EXPORT BOOL
_class_isFutureClass(Class _Nullable cls
)
734 OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0);
736 /// Returns true if the class is an ABI stable Swift class. (Despite
737 /// the name, this does NOT return true for Swift classes built with
738 /// Swift versions prior to 5.0.)
739 OBJC_EXPORT BOOL
_class_isSwift(Class _Nullable cls
)
740 OBJC_AVAILABLE(10.16, 14.0, 14.0, 7.0, 5.0);
742 // API to only be called by root classes like NSObject or NSProxy
746 _objc_rootRetain(id _Nonnull obj
)
747 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
751 _objc_rootRelease(id _Nonnull obj
)
752 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
756 _objc_rootReleaseWasZero(id _Nonnull obj
)
757 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
761 _objc_rootTryRetain(id _Nonnull obj
)
762 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
766 _objc_rootIsDeallocating(id _Nonnull obj
)
767 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
771 _objc_rootAutorelease(id _Nonnull obj
)
772 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
776 _objc_rootRetainCount(id _Nonnull obj
)
777 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
781 _objc_rootInit(id _Nonnull obj
)
782 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
786 _objc_rootAllocWithZone(Class _Nonnull cls
, malloc_zone_t
* _Nullable zone
)
787 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
791 _objc_rootAlloc(Class _Nonnull cls
)
792 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
796 _objc_rootDealloc(id _Nonnull obj
)
797 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
801 _objc_rootFinalize(id _Nonnull obj
)
802 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
805 malloc_zone_t
* _Nonnull
806 _objc_rootZone(id _Nonnull obj
)
807 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
811 _objc_rootHash(id _Nonnull obj
)
812 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
816 objc_autoreleasePoolPush(void)
817 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
821 objc_autoreleasePoolPop(void * _Nonnull context
)
822 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
825 OBJC_EXPORT id _Nullable
826 objc_alloc(Class _Nullable cls
)
827 OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0);
829 OBJC_EXPORT id _Nullable
830 objc_allocWithZone(Class _Nullable cls
)
831 OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0);
833 OBJC_EXPORT id _Nullable
834 objc_alloc_init(Class _Nullable cls
)
835 OBJC_AVAILABLE(10.14.4, 12.2, 12.2, 5.2, 3.2);
837 OBJC_EXPORT id _Nullable
838 objc_opt_new(Class _Nullable cls
)
839 OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0);
841 OBJC_EXPORT id _Nullable
842 objc_opt_self(id _Nullable obj
)
843 OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0);
845 OBJC_EXPORT Class _Nullable
846 objc_opt_class(id _Nullable obj
)
847 OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0);
850 objc_opt_respondsToSelector(id _Nullable obj
, SEL _Nullable sel
)
851 OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0);
854 objc_opt_isKindOfClass(id _Nullable obj
, Class _Nullable cls
)
855 OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0);
859 objc_sync_try_enter(id _Nonnull obj
)
860 OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0);
862 OBJC_EXPORT id _Nullable
863 objc_retain(id _Nullable obj
)
864 __asm__("_objc_retain")
865 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
868 objc_release(id _Nullable obj
)
869 __asm__("_objc_release")
870 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
872 OBJC_EXPORT id _Nullable
873 objc_autorelease(id _Nullable obj
)
874 __asm__("_objc_autorelease")
875 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
877 // Prepare a value at +1 for return through a +0 autoreleasing convention.
878 OBJC_EXPORT id _Nullable
879 objc_autoreleaseReturnValue(id _Nullable obj
)
880 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
882 // Prepare a value at +0 for return through a +0 autoreleasing convention.
883 OBJC_EXPORT id _Nullable
884 objc_retainAutoreleaseReturnValue(id _Nullable obj
)
885 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
887 // Accept a value returned through a +0 autoreleasing convention for use at +1.
888 OBJC_EXPORT id _Nullable
889 objc_retainAutoreleasedReturnValue(id _Nullable obj
)
890 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
892 // Accept a value returned through a +0 autoreleasing convention for use at +0.
893 OBJC_EXPORT id _Nullable
894 objc_unsafeClaimAutoreleasedReturnValue(id _Nullable obj
)
895 OBJC_AVAILABLE(10.11, 9.0, 9.0, 1.0, 2.0);
898 objc_storeStrong(id _Nullable
* _Nonnull location
, id _Nullable obj
)
899 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
901 OBJC_EXPORT id _Nullable
902 objc_retainAutorelease(id _Nullable obj
)
903 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
906 OBJC_EXPORT id _Nullable
907 objc_retain_autorelease(id _Nullable obj
)
908 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
910 OBJC_EXPORT id _Nullable
911 objc_loadWeakRetained(id _Nullable
* _Nonnull location
)
912 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
914 OBJC_EXPORT id _Nullable
915 objc_initWeak(id _Nullable
* _Nonnull location
, id _Nullable val
)
916 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
918 // Like objc_storeWeak, but stores nil if the new object is deallocating
919 // or the new object's class does not support weak references.
920 // Returns the value stored (either the new object or nil).
921 OBJC_EXPORT id _Nullable
922 objc_storeWeakOrNil(id _Nullable
* _Nonnull location
, id _Nullable obj
)
923 OBJC_AVAILABLE(10.11, 9.0, 9.0, 1.0, 2.0);
925 // Like objc_initWeak, but stores nil if the new object is deallocating
926 // or the new object's class does not support weak references.
927 // Returns the value stored (either the new object or nil).
928 OBJC_EXPORT id _Nullable
929 objc_initWeakOrNil(id _Nullable
* _Nonnull location
, id _Nullable val
)
930 OBJC_AVAILABLE(10.11, 9.0, 9.0, 1.0, 2.0);
933 objc_destroyWeak(id _Nullable
* _Nonnull location
)
934 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
937 objc_copyWeak(id _Nullable
* _Nonnull to
, id _Nullable
* _Nonnull from
)
938 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
941 objc_moveWeak(id _Nullable
* _Nonnull to
, id _Nullable
* _Nonnull from
)
942 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
946 _objc_autoreleasePoolPrint(void)
947 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
950 objc_should_deallocate(id _Nonnull object
)
951 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
954 objc_clear_deallocating(id _Nonnull object
)
955 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
958 // to make CF link for now
960 OBJC_EXPORT
void * _Nonnull
961 _objc_autoreleasePoolPush(void)
962 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
965 _objc_autoreleasePoolPop(void * _Nonnull context
)
966 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
970 * Load a classref, which is a chunk of data containing a class
971 * pointer. May perform initialization and rewrite the classref to
972 * point to a new object, if needed. Returns the loaded Class.
974 * In particular, if the classref points to a stub class (indicated
975 * by setting the bottom bit of the class pointer to 1), then this
976 * will call the stub's initializer and then replace the classref
977 * value with the value returned by the initializer.
979 * @param clsref The classref to load.
980 * @return The loaded Class pointer.
983 OBJC_EXPORT _Nullable Class
984 objc_loadClassref(_Nullable Class
* _Nonnull clsref
)
985 OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0);
989 // Extra @encode data for XPC, or NULL
990 OBJC_EXPORT
const char * _Nullable
991 _protocol_getMethodTypeEncoding(Protocol
* _Nonnull proto
, SEL _Nonnull sel
,
992 BOOL isRequiredMethod
, BOOL isInstanceMethod
)
993 OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0, 2.0);
997 * Function type for a function that is called when a realized class
998 * is about to be initialized.
1000 * @param context The context pointer the function was registered with.
1001 * @param cls The class that's about to be initialized.
1004 typedef void (*_objc_func_willInitializeClass
)(void * _Nullable context
, Class _Nonnull cls
);
1007 * Add a function to be called when a realized class is about to be
1008 * initialized. The class can be queried and manipulated using runtime
1009 * functions. Don't message it.
1011 * When adding a new function, that function is immediately called with all
1012 * realized classes that are already initialized or are in the process
1013 * of initialization.
1015 * @param func The function to add.
1016 * @param context A context pointer that will be passed to the function when called.
1018 #define OBJC_WILLINITIALIZECLASSFUNC_DEFINED 1
1019 OBJC_EXPORT
void _objc_addWillInitializeClassFunc(_objc_func_willInitializeClass _Nonnull func
, void * _Nullable context
)
1020 OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 4.0);
1022 // Replicate the conditionals in objc-config.h for packed isa, indexed isa, and preopt caches
1023 #if __ARM_ARCH_7K__ >= 2 || (__arm64__ && !__LP64__) || \
1024 !(!__LP64__ || TARGET_OS_WIN32 || \
1025 (TARGET_OS_SIMULATOR && !TARGET_OS_MACCATALYST && !__arm64__))
1026 OBJC_EXPORT
const uintptr_t _objc_has_weak_formation_callout
;
1027 #define OBJC_WEAK_FORMATION_CALLOUT_DEFINED 1
1029 #define OBJC_WEAK_FORMATION_CALLOUT_DEFINED 0
1032 #if defined(__arm64__) && TARGET_OS_IOS && !TARGET_OS_SIMULATOR && !TARGET_OS_MACCATALYST
1033 #define CONFIG_USE_PREOPT_CACHES 1
1035 #define CONFIG_USE_PREOPT_CACHES 0
1040 // Helper function for objc4 tests only! Do not call this yourself
1041 // for any reason ever.
1042 OBJC_EXPORT
void _method_setImplementationRawUnsafe(Method _Nonnull m
, IMP _Nonnull imp
)
1043 OBJC_AVAILABLE(10.16, 14.0, 14.0, 7.0, 5.0);
1046 // API to only be called by classes that provide their own reference count storage
1049 _objc_deallocOnMainThreadHelper(void * _Nullable context
)
1050 OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
1053 // Declarations for internal methods used for custom weak reference
1054 // implementations. These declarations ensure that the compiler knows
1055 // to exclude these methods from NS_DIRECT_MEMBERS. Do NOT implement
1056 // these methods unless you really know what you're doing.
1057 @interface
NSObject ()
1059 - (BOOL
)_isDeallocating
;
1063 // On async versus sync deallocation and the _dealloc2main flag
1067 // If order matters, then code must always: [self dealloc].
1068 // If order doesn't matter, then always async should be safe.
1072 // The _dealloc2main bit is set for GUI objects that may be retained by other
1073 // threads. Once deallocation begins on the main thread, doing more async
1074 // deallocation will at best cause extra UI latency and at worst cause
1075 // use-after-free bugs in unretained delegate style patterns. Yes, this is
1076 // extremely fragile. Yes, in the long run, developers should switch to weak
1079 // Note is NOT safe to do any equality check against the result of
1080 // dispatch_get_current_queue(). The main thread can and does drain more than
1081 // one dispatch queue. That is why we call pthread_main_np().
1085 _OBJC_RESURRECT_OBJECT
= -1, /* _logicBlock has called -retain, and scheduled a -release for later. */
1086 _OBJC_DEALLOC_OBJECT_NOW
= 1, /* call [self dealloc] immediately. */
1087 _OBJC_DEALLOC_OBJECT_LATER
= 2 /* call [self dealloc] on the main queue. */
1088 } _objc_object_disposition_t
;
1090 #define _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC_BLOCK(_rc_ivar, _logicBlock) \
1092 /* this will fail to compile if _rc_ivar is an unsigned type */ \
1093 int _retain_count_ivar_must_not_be_unsigned[0L - (__typeof__(_rc_ivar))-1] __attribute__((unused)); \
1094 __typeof__(_rc_ivar) _prev = __sync_fetch_and_add(&_rc_ivar, 2); \
1095 if (_prev < -2) { /* specifically allow resurrection from logical 0. */ \
1096 __builtin_trap(); /* BUG: retain of over-released ref */ \
1100 -(oneway void)release { \
1101 __typeof__(_rc_ivar) _prev = __sync_fetch_and_sub(&_rc_ivar, 2); \
1104 } else if (_prev < 0) { \
1105 __builtin_trap(); /* BUG: over-release */ \
1107 _objc_object_disposition_t fate = _logicBlock(self); \
1108 if (fate == _OBJC_RESURRECT_OBJECT) { \
1111 /* mark the object as deallocating. */ \
1112 if (!__sync_bool_compare_and_swap(&_rc_ivar, -2, 1)) { \
1113 __builtin_trap(); /* BUG: dangling ref did a retain */ \
1115 if (fate == _OBJC_DEALLOC_OBJECT_NOW) { \
1117 } else if (fate == _OBJC_DEALLOC_OBJECT_LATER) { \
1118 dispatch_barrier_async_f(dispatch_get_main_queue(), self, \
1119 _objc_deallocOnMainThreadHelper); \
1121 __builtin_trap(); /* BUG: bogus fate value */ \
1124 -(NSUInteger)retainCount { \
1125 return (NSUInteger)(_rc_ivar + 2) >> 1; \
1127 -(BOOL)_tryRetain { \
1128 __typeof__(_rc_ivar) _prev; \
1133 } else if (_prev == -2) { \
1135 } else if (_prev < -2) { \
1136 __builtin_trap(); /* BUG: over-release elsewhere */ \
1138 } while ( ! __sync_bool_compare_and_swap(&_rc_ivar, _prev, _prev + 2)); \
1141 -(BOOL)_isDeallocating { \
1142 if (_rc_ivar == -2) { \
1144 } else if (_rc_ivar < -2) { \
1145 __builtin_trap(); /* BUG: over-release elsewhere */ \
1147 return (_rc_ivar & 1) != 0; \
1150 #define _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC(_rc_ivar, _dealloc2main) \
1151 _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC_BLOCK(_rc_ivar, (^(id _self_ __attribute__((unused))) { \
1152 if ((_dealloc2main) && !pthread_main_np()) { \
1153 return _OBJC_DEALLOC_OBJECT_LATER; \
1155 return _OBJC_DEALLOC_OBJECT_NOW; \
1159 #define _OBJC_SUPPORTED_INLINE_REFCNT(_rc_ivar) _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC(_rc_ivar, 0)
1160 #define _OBJC_SUPPORTED_INLINE_REFCNT_WITH_DEALLOC2MAIN(_rc_ivar) _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC(_rc_ivar, 1)
1163 // C cache_t wrappers for objcdt and the IMP caches test tool
1166 struct preopt_cache_t
;
1167 OBJC_EXPORT
struct bucket_t
* _Nonnull
objc_cache_buckets(const struct cache_t
* _Nonnull cache
);
1168 OBJC_EXPORT
size_t objc_cache_bytesForCapacity(uint32_t cap
);
1169 OBJC_EXPORT
uint32_t objc_cache_occupied(const struct cache_t
* _Nonnull cache
);
1170 OBJC_EXPORT
unsigned objc_cache_capacity(const struct cache_t
* _Nonnull cache
);
1172 #if CONFIG_USE_PREOPT_CACHES
1174 OBJC_EXPORT
bool objc_cache_isConstantOptimizedCache(const struct cache_t
* _Nonnull cache
, bool strict
, uintptr_t empty_addr
);
1175 OBJC_EXPORT
unsigned objc_cache_preoptCapacity(const struct cache_t
* _Nonnull cache
);
1176 OBJC_EXPORT Class _Nonnull
objc_cache_preoptFallbackClass(const struct cache_t
* _Nonnull cache
);
1177 OBJC_EXPORT
const struct preopt_cache_t
* _Nonnull
objc_cache_preoptCache(const struct cache_t
* _Nonnull cache
);