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@
24 #ifndef _OBJC_RUNTIME_OLD_H
25 #define _OBJC_RUNTIME_OLD_H
27 #include "objc-private.h"
31 #define CLS_INITIALIZED 0x4
32 #define CLS_POSING 0x8
33 #define CLS_MAPPED 0x10
34 #define CLS_FLUSH_CACHE 0x20
35 #define CLS_GROW_CACHE 0x40
36 #define CLS_NEED_BIND 0x80
37 #define CLS_METHOD_ARRAY 0x100
38 // the JavaBridge constructs classes with these markers
39 #define CLS_JAVA_HYBRID 0x200
40 #define CLS_JAVA_CLASS 0x400
41 // thread-safe +initialize
42 #define CLS_INITIALIZING 0x800
44 #define CLS_FROM_BUNDLE 0x1000
46 #define CLS_HAS_CXX_STRUCTORS 0x2000
47 // Lazy method list arrays
48 #define CLS_NO_METHOD_ARRAY 0x4000
49 // +load implementation
50 #define CLS_HAS_LOAD_METHOD 0x8000
51 // objc_allocateClassPair API
52 #define CLS_CONSTRUCTING 0x10000
54 #define CLS_HIDDEN 0x20000
55 // available for use; was CLS_FINALIZE_ON_MAIN_THREAD
56 #define CLS_40000 0x40000
57 // Lazy property list arrays
58 #define CLS_NO_PROPERTY_ARRAY 0x80000
59 // +load implementation
60 #define CLS_CONNECTED 0x100000
61 #define CLS_LOADED 0x200000
62 // objc_allocateClassPair API
63 #define CLS_CONSTRUCTED 0x400000
64 // class is leaf for cache flushing
65 #define CLS_LEAF 0x800000
66 // class instances may have associative references
67 #define CLS_INSTANCES_HAVE_ASSOCIATED_OBJECTS 0x1000000
68 // class has instance-specific GC layout
69 #define CLS_HAS_INSTANCE_SPECIFIC_LAYOUT 0x2000000
70 // class compiled with ARC
71 #define CLS_IS_ARC 0x4000000
72 // class is not ARC but has ARC-style weak ivar layout
73 #define CLS_HAS_WEAK_WITHOUT_ARC 0x8000000
76 // Terminator for array of method lists
77 #define END_OF_METHODS_LIST ((struct old_method_list*)-1)
79 #define ISCLASS(cls) (((cls)->info & CLS_CLASS) != 0)
80 #define ISMETA(cls) (((cls)->info & CLS_META) != 0)
81 #define GETMETA(cls) (ISMETA(cls) ? (cls) : (cls)->ISA())
84 struct old_class_ext
{
86 const uint8_t *weak_ivar_layout
;
87 struct old_property_list
**propertyLists
;
93 struct old_method_list
*instance_methods
;
94 struct old_method_list
*class_methods
;
95 struct old_protocol_list
*protocols
;
96 // Fields below this point are in version 7 or later only.
98 struct old_property_list
*instance_properties
;
99 // Check size for fields below this point.
100 struct old_property_list
*class_properties
;
102 bool hasClassPropertiesField() const {
103 return size
>= offsetof(old_category
, class_properties
) + sizeof(class_properties
);
116 struct old_ivar_list
{
121 /* variable length structure */
122 struct old_ivar ivar_list
[1];
132 struct old_method_list
{
139 /* variable length structure */
140 struct old_method method_list
[1];
143 struct old_protocol
{
145 const char *protocol_name
;
146 struct old_protocol_list
*protocol_list
;
147 struct objc_method_description_list
*instance_methods
;
148 struct objc_method_description_list
*class_methods
;
151 struct old_protocol_list
{
152 struct old_protocol_list
*next
;
154 struct old_protocol
*list
[1];
157 struct old_protocol_ext
{
159 struct objc_method_description_list
*optional_instance_methods
;
160 struct objc_method_description_list
*optional_class_methods
;
161 struct old_property_list
*instance_properties
;
162 const char **extendedMethodTypes
;
163 struct old_property_list
*class_properties
;
165 bool hasClassPropertiesField() const {
166 return size
>= offsetof(old_protocol_ext
, class_properties
) + sizeof(class_properties
);
171 struct old_property
{
173 const char *attributes
;
176 struct old_property_list
{
179 struct old_property first
;
183 struct objc_class
: objc_object
{
188 uint32_t instance_size
;
189 struct old_ivar_list
*ivars
;
190 struct old_method_list
**methodLists
;
192 struct old_protocol_list
*protocols
;
194 const uint8_t *ivar_layout
;
195 struct old_class_ext
*ext
;
197 void setInfo(uint32_t set
) {
198 OSAtomicOr32Barrier(set
, (volatile uint32_t *)&info
);
201 void clearInfo(uint32_t clear
) {
202 OSAtomicXor32Barrier(clear
, (volatile uint32_t *)&info
);
206 // set and clear must not overlap
207 void changeInfo(uint32_t set
, uint32_t clear
) {
208 assert((set
& clear
) == 0);
213 newf
= (oldf
| set
) & ~clear
;
214 } while (!OSAtomicCompareAndSwap32Barrier(oldf
, newf
, (volatile int32_t *)&info
));
218 // set_superclass propagates the flag from the superclass.
219 return info
& CLS_HAS_CXX_STRUCTORS
;
223 return hasCxxCtor(); // one bit for both ctor and dtor
226 // Return YES if the class's ivars are managed by ARC,
227 // or the class is MRC but has ARC-style weak ivars.
228 bool hasAutomaticIvars() {
229 return info
& (CLS_IS_ARC
| CLS_HAS_WEAK_WITHOUT_ARC
);
232 // Return YES if the class's ivars are managed by ARC.
234 return info
& CLS_IS_ARC
;
240 void setHasCustomRR(bool = false) { }
241 void setHasDefaultRR() { }
242 void printCustomRR(bool) { }
244 bool hasCustomAWZ() {
247 void setHasCustomAWZ(bool = false) { }
248 void setHasDefaultAWZ() { }
249 void printCustomAWZ(bool) { }
251 bool instancesHaveAssociatedObjects() {
252 return info
& CLS_INSTANCES_HAVE_ASSOCIATED_OBJECTS
;
255 void setInstancesHaveAssociatedObjects() {
256 setInfo(CLS_INSTANCES_HAVE_ASSOCIATED_OBJECTS
);
259 bool shouldGrowCache() {
260 return info
& CLS_GROW_CACHE
;
263 void setShouldGrowCache(bool grow
) {
264 if (grow
) setInfo(CLS_GROW_CACHE
);
265 else clearInfo(CLS_GROW_CACHE
);
268 // +initialize bits are stored on the metaclass only
269 bool isInitializing() {
270 return getMeta()->info
& CLS_INITIALIZING
;
273 // +initialize bits are stored on the metaclass only
274 void setInitializing() {
275 getMeta()->setInfo(CLS_INITIALIZING
);
278 // +initialize bits are stored on the metaclass only
279 bool isInitialized() {
280 return getMeta()->info
& CLS_INITIALIZED
;
283 // +initialize bits are stored on the metaclass only
284 void setInitialized() {
285 getMeta()->changeInfo(CLS_INITIALIZED
, CLS_INITIALIZING
);
289 // A class registered for +load is ready for +load to be called
290 // if it is connected.
291 return isConnected();
300 const char *mangledName() { return name
; }
301 const char *demangledName() { return name
; }
302 const char *nameForLogging() { return name
; }
305 return info
& CLS_META
;
308 // NOT identical to this->ISA() when this is a metaclass
310 if (isMetaClass()) return (Class
)this;
311 else return this->ISA();
314 // May be unaligned depending on class's ivars.
315 uint32_t unalignedInstanceStart() {
316 // This is not simply superclass->instance_size.
317 // superclass->instance_size is padded to its sizeof() boundary,
318 // which may envelop one of this class's ivars.
319 // That in turn would break ARC-style ivar layouts.
320 // Instead, we use the address of this class's first ivar when possible.
321 if (!superclass
) return 0;
322 if (!ivars
|| ivars
->ivar_count
== 0) return superclass
->instance_size
;
323 return ivars
->ivar_list
[0].ivar_offset
;
326 // Class's instance start rounded up to a pointer-size boundary.
327 // This is used for ARC layout bitmaps.
328 uint32_t alignedInstanceStart() {
329 return word_align(unalignedInstanceStart());
333 // May be unaligned depending on class's ivars.
334 uint32_t unalignedInstanceSize() {
335 return instance_size
;
338 // Class's ivar size rounded up to a pointer-size boundary.
339 uint32_t alignedInstanceSize() {
340 return word_align(unalignedInstanceSize());
343 size_t instanceSize(size_t extraBytes
) {
344 size_t size
= alignedInstanceSize() + extraBytes
;
345 // CF requires all objects be at least 16 bytes.
346 if (size
< 16) size
= 16;
353 #include "hashtable2.h"
357 #define oldprotocol(proto) ((struct old_protocol *)proto)
358 #define oldmethod(meth) ((struct old_method *)meth)
359 #define oldcategory(cat) ((struct old_category *)cat)
360 #define oldivar(ivar) ((struct old_ivar *)ivar)
361 #define oldproperty(prop) ((struct old_property *)prop)
363 extern NXHashTable
*class_hash
;
365 extern void unload_class(Class cls
);
367 extern IMP
lookupNamedMethodInMethodList(struct old_method_list
*mlist
, const char *meth_name
);
368 extern void _objc_insertMethods(Class cls
, struct old_method_list
*mlist
, struct old_category
*cat
);
369 extern void _objc_removeMethods(Class cls
, struct old_method_list
*mlist
);
370 extern void _objc_flush_caches (Class cls
);
371 extern bool _class_addProperties(Class cls
, struct old_property_list
*additions
);
372 extern bool _class_hasLoadMethod(Class cls
);
373 extern void change_class_references(Class imposter
, Class original
, Class copy
, bool changeSuperRefs
);
374 extern void flush_marked_caches(void);
375 extern void set_superclass(Class cls
, Class supercls
, bool cls_is_new
);
376 extern void try_free(const void *p
);
378 extern struct old_property
*property_list_nth(const struct old_property_list
*plist
, uint32_t i
);
379 extern struct old_property
**copyPropertyList(struct old_property_list
*plist
, unsigned int *outCount
);
381 extern struct objc_method_description
* lookup_protocol_method(struct old_protocol
*proto
, SEL aSel
, bool isRequiredMethod
, bool isInstanceMethod
, bool recursive
);
383 // used by flush_caches outside objc-cache.m
384 extern void _cache_flush(Class cls
);
385 #ifdef OBJC_INSTRUMENTED
386 extern unsigned int LinearFlushCachesCount
;
387 extern unsigned int LinearFlushCachesVisitedCount
;
388 extern unsigned int MaxLinearFlushCachesVisitedCount
;
389 extern unsigned int NonlinearFlushCachesCount
;
390 extern unsigned int NonlinearFlushCachesClassCount
;
391 extern unsigned int NonlinearFlushCachesVisitedCount
;
392 extern unsigned int MaxNonlinearFlushCachesVisitedCount
;
393 extern unsigned int IdealFlushCachesCount
;
394 extern unsigned int MaxIdealFlushCachesCount
;