objc-runtime-old.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /*
  2. * Copyright (c) 1999-2007 Apple Inc. All Rights Reserved.
  3. *
  4. * @APPLE_LICENSE_HEADER_START@
  5. *
  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
  11. * file.
  12. *
  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.
  20. *
  21. * @APPLE_LICENSE_HEADER_END@
  22. */
  23. #ifndef _OBJC_RUNTIME_OLD_H
  24. #define _OBJC_RUNTIME_OLD_H
  25. #include "objc-private.h"
  26. #define CLS_CLASS 0x1
  27. #define CLS_META 0x2
  28. #define CLS_INITIALIZED 0x4
  29. #define CLS_POSING 0x8
  30. #define CLS_MAPPED 0x10
  31. #define CLS_FLUSH_CACHE 0x20
  32. #define CLS_GROW_CACHE 0x40
  33. #define CLS_NEED_BIND 0x80
  34. #define CLS_METHOD_ARRAY 0x100
  35. // the JavaBridge constructs classes with these markers
  36. #define CLS_JAVA_HYBRID 0x200
  37. #define CLS_JAVA_CLASS 0x400
  38. // thread-safe +initialize
  39. #define CLS_INITIALIZING 0x800
  40. // bundle unloading
  41. #define CLS_FROM_BUNDLE 0x1000
  42. // C++ ivar support
  43. #define CLS_HAS_CXX_STRUCTORS 0x2000
  44. // Lazy method list arrays
  45. #define CLS_NO_METHOD_ARRAY 0x4000
  46. // +load implementation
  47. #define CLS_HAS_LOAD_METHOD 0x8000
  48. // objc_allocateClassPair API
  49. #define CLS_CONSTRUCTING 0x10000
  50. // visibility=hidden
  51. #define CLS_HIDDEN 0x20000
  52. // available for use; was CLS_FINALIZE_ON_MAIN_THREAD
  53. #define CLS_40000 0x40000
  54. // Lazy property list arrays
  55. #define CLS_NO_PROPERTY_ARRAY 0x80000
  56. // +load implementation
  57. #define CLS_CONNECTED 0x100000
  58. #define CLS_LOADED 0x200000
  59. // objc_allocateClassPair API
  60. #define CLS_CONSTRUCTED 0x400000
  61. // class is leaf for cache flushing
  62. #define CLS_LEAF 0x800000
  63. // class instances may have associative references
  64. #define CLS_INSTANCES_HAVE_ASSOCIATED_OBJECTS 0x1000000
  65. // available for use; was CLS_HAS_INSTANCE_SPECIFIC_LAYOUT
  66. #define CLS_2000000 0x2000000
  67. // class compiled with ARC
  68. #define CLS_IS_ARC 0x4000000
  69. // class is not ARC but has ARC-style weak ivar layout
  70. #define CLS_HAS_WEAK_WITHOUT_ARC 0x8000000
  71. // Terminator for array of method lists
  72. #define END_OF_METHODS_LIST ((struct old_method_list*)-1)
  73. #define ISCLASS(cls) (((cls)->info & CLS_CLASS) != 0)
  74. #define ISMETA(cls) (((cls)->info & CLS_META) != 0)
  75. #define GETMETA(cls) (ISMETA(cls) ? (cls) : (cls)->ISA())
  76. struct old_class_ext {
  77. uint32_t size;
  78. const uint8_t *weak_ivar_layout;
  79. struct old_property_list **propertyLists;
  80. };
  81. struct old_category {
  82. char *category_name;
  83. char *class_name;
  84. struct old_method_list *instance_methods;
  85. struct old_method_list *class_methods;
  86. struct old_protocol_list *protocols;
  87. // Fields below this point are in version 7 or later only.
  88. uint32_t size;
  89. struct old_property_list *instance_properties;
  90. // Check size for fields below this point.
  91. struct old_property_list *class_properties;
  92. bool hasClassPropertiesField() const {
  93. return size >= offsetof(old_category, class_properties) + sizeof(class_properties);
  94. }
  95. };
  96. struct old_ivar {
  97. char *ivar_name;
  98. char *ivar_type;
  99. int ivar_offset;
  100. #ifdef __LP64__
  101. int space;
  102. #endif
  103. };
  104. struct old_ivar_list {
  105. int ivar_count;
  106. #ifdef __LP64__
  107. int space;
  108. #endif
  109. /* variable length structure */
  110. struct old_ivar ivar_list[1];
  111. };
  112. struct old_method {
  113. SEL method_name;
  114. char *method_types;
  115. IMP method_imp;
  116. };
  117. struct old_method_list {
  118. void *obsolete;
  119. int method_count;
  120. #ifdef __LP64__
  121. int space;
  122. #endif
  123. /* variable length structure */
  124. struct old_method method_list[1];
  125. };
  126. struct old_protocol {
  127. Class isa;
  128. const char *protocol_name;
  129. struct old_protocol_list *protocol_list;
  130. struct objc_method_description_list *instance_methods;
  131. struct objc_method_description_list *class_methods;
  132. };
  133. struct old_protocol_list {
  134. struct old_protocol_list *next;
  135. long count;
  136. struct old_protocol *list[1];
  137. };
  138. struct old_protocol_ext {
  139. uint32_t size;
  140. struct objc_method_description_list *optional_instance_methods;
  141. struct objc_method_description_list *optional_class_methods;
  142. struct old_property_list *instance_properties;
  143. const char **extendedMethodTypes;
  144. struct old_property_list *class_properties;
  145. bool hasClassPropertiesField() const {
  146. return size >= offsetof(old_protocol_ext, class_properties) + sizeof(class_properties);
  147. }
  148. };
  149. struct old_property {
  150. const char *name;
  151. const char *attributes;
  152. };
  153. struct old_property_list {
  154. uint32_t entsize;
  155. uint32_t count;
  156. struct old_property first;
  157. };
  158. struct objc_class : objc_object {
  159. Class superclass;
  160. const char *name;
  161. uint32_t version;
  162. uint32_t info;
  163. uint32_t instance_size;
  164. struct old_ivar_list *ivars;
  165. struct old_method_list **methodLists;
  166. Cache cache;
  167. struct old_protocol_list *protocols;
  168. // CLS_EXT only
  169. const uint8_t *ivar_layout;
  170. struct old_class_ext *ext;
  171. void setInfo(uint32_t set) {
  172. OSAtomicOr32Barrier(set, (volatile uint32_t *)&info);
  173. }
  174. void clearInfo(uint32_t clear) {
  175. OSAtomicXor32Barrier(clear, (volatile uint32_t *)&info);
  176. }
  177. // set and clear must not overlap
  178. void changeInfo(uint32_t set, uint32_t clear) {
  179. ASSERT((set & clear) == 0);
  180. uint32_t oldf, newf;
  181. do {
  182. oldf = this->info;
  183. newf = (oldf | set) & ~clear;
  184. } while (!OSAtomicCompareAndSwap32Barrier(oldf, newf, (volatile int32_t *)&info));
  185. }
  186. bool hasCxxCtor() {
  187. // set_superclass propagates the flag from the superclass.
  188. return info & CLS_HAS_CXX_STRUCTORS;
  189. }
  190. bool hasCxxDtor() {
  191. return hasCxxCtor(); // one bit for both ctor and dtor
  192. }
  193. // Return YES if the class's ivars are managed by ARC,
  194. // or the class is MRC but has ARC-style weak ivars.
  195. bool hasAutomaticIvars() {
  196. return info & (CLS_IS_ARC | CLS_HAS_WEAK_WITHOUT_ARC);
  197. }
  198. // Return YES if the class's ivars are managed by ARC.
  199. bool isARC() {
  200. return info & CLS_IS_ARC;
  201. }
  202. bool hasCustomRR() {
  203. return true;
  204. }
  205. bool hasCustomAWZ() {
  206. return true;
  207. }
  208. bool forbidsAssociatedObjects() {
  209. // Old runtime doesn't support forbidding associated objects.
  210. return false;
  211. }
  212. bool instancesHaveAssociatedObjects() {
  213. return info & CLS_INSTANCES_HAVE_ASSOCIATED_OBJECTS;
  214. }
  215. void setInstancesHaveAssociatedObjects() {
  216. setInfo(CLS_INSTANCES_HAVE_ASSOCIATED_OBJECTS);
  217. }
  218. bool shouldGrowCache() {
  219. return info & CLS_GROW_CACHE;
  220. }
  221. void setShouldGrowCache(bool grow) {
  222. if (grow) setInfo(CLS_GROW_CACHE);
  223. else clearInfo(CLS_GROW_CACHE);
  224. }
  225. // +initialize bits are stored on the metaclass only
  226. bool isInitializing() {
  227. return getMeta()->info & CLS_INITIALIZING;
  228. }
  229. // +initialize bits are stored on the metaclass only
  230. void setInitializing() {
  231. getMeta()->setInfo(CLS_INITIALIZING);
  232. }
  233. // +initialize bits are stored on the metaclass only
  234. bool isInitialized() {
  235. return getMeta()->info & CLS_INITIALIZED;
  236. }
  237. // +initialize bits are stored on the metaclass only
  238. void setInitialized() {
  239. getMeta()->changeInfo(CLS_INITIALIZED, CLS_INITIALIZING);
  240. }
  241. bool isLoadable() {
  242. // A class registered for +load is ready for +load to be called
  243. // if it is connected.
  244. return isConnected();
  245. }
  246. IMP getLoadMethod();
  247. bool isFuture();
  248. bool isConnected();
  249. const char *mangledName() { return name; }
  250. const char *demangledName() { return name; }
  251. const char *nameForLogging() { return name; }
  252. bool isRootClass() {
  253. return superclass == nil;
  254. }
  255. bool isRootMetaclass() {
  256. return ISA() == (Class)this;
  257. }
  258. bool isMetaClass() {
  259. return info & CLS_META;
  260. }
  261. // NOT identical to this->ISA() when this is a metaclass
  262. Class getMeta() {
  263. if (isMetaClass()) return (Class)this;
  264. else return this->ISA();
  265. }
  266. // May be unaligned depending on class's ivars.
  267. uint32_t unalignedInstanceStart() {
  268. // This is not simply superclass->instance_size.
  269. // superclass->instance_size is padded to its sizeof() boundary,
  270. // which may envelop one of this class's ivars.
  271. // That in turn would break ARC-style ivar layouts.
  272. // Instead, we use the address of this class's first ivar when possible.
  273. if (!superclass) return 0;
  274. if (!ivars || ivars->ivar_count == 0) return superclass->instance_size;
  275. return ivars->ivar_list[0].ivar_offset;
  276. }
  277. // Class's instance start rounded up to a pointer-size boundary.
  278. // This is used for ARC layout bitmaps.
  279. uint32_t alignedInstanceStart() {
  280. return word_align(unalignedInstanceStart());
  281. }
  282. // May be unaligned depending on class's ivars.
  283. uint32_t unalignedInstanceSize() {
  284. return instance_size;
  285. }
  286. // Class's ivar size rounded up to a pointer-size boundary.
  287. uint32_t alignedInstanceSize() {
  288. return word_align(unalignedInstanceSize());
  289. }
  290. size_t instanceSize(size_t extraBytes) {
  291. size_t size = alignedInstanceSize() + extraBytes;
  292. // CF requires all objects be at least 16 bytes.
  293. if (size < 16) size = 16;
  294. return size;
  295. }
  296. };
  297. #include "hashtable2.h"
  298. __BEGIN_DECLS
  299. #define oldprotocol(proto) ((struct old_protocol *)proto)
  300. #define oldmethod(meth) ((struct old_method *)meth)
  301. #define oldcategory(cat) ((struct old_category *)cat)
  302. #define oldivar(ivar) ((struct old_ivar *)ivar)
  303. #define oldproperty(prop) ((struct old_property *)prop)
  304. extern NXHashTable *class_hash;
  305. extern void unload_class(Class cls);
  306. extern IMP lookupNamedMethodInMethodList(struct old_method_list *mlist, const char *meth_name);
  307. extern void _objc_insertMethods(Class cls, struct old_method_list *mlist, struct old_category *cat);
  308. extern void _objc_removeMethods(Class cls, struct old_method_list *mlist);
  309. extern void _objc_flush_caches (Class cls);
  310. extern bool _class_addProperties(Class cls, struct old_property_list *additions);
  311. extern bool _class_hasLoadMethod(Class cls);
  312. extern void change_class_references(Class imposter, Class original, Class copy, bool changeSuperRefs);
  313. extern void flush_marked_caches(void);
  314. extern void set_superclass(Class cls, Class supercls, bool cls_is_new);
  315. extern void try_free(const void *p);
  316. extern struct old_property *property_list_nth(const struct old_property_list *plist, uint32_t i);
  317. extern struct old_property **copyPropertyList(struct old_property_list *plist, unsigned int *outCount);
  318. extern struct objc_method_description * lookup_protocol_method(struct old_protocol *proto, SEL aSel, bool isRequiredMethod, bool isInstanceMethod, bool recursive);
  319. // used by flush_caches outside objc-cache.m
  320. extern void _cache_flush(Class cls);
  321. #ifdef OBJC_INSTRUMENTED
  322. extern unsigned int LinearFlushCachesCount;
  323. extern unsigned int LinearFlushCachesVisitedCount;
  324. extern unsigned int MaxLinearFlushCachesVisitedCount;
  325. extern unsigned int NonlinearFlushCachesCount;
  326. extern unsigned int NonlinearFlushCachesClassCount;
  327. extern unsigned int NonlinearFlushCachesVisitedCount;
  328. extern unsigned int MaxNonlinearFlushCachesVisitedCount;
  329. extern unsigned int IdealFlushCachesCount;
  330. extern unsigned int MaxIdealFlushCachesCount;
  331. #endif
  332. __END_DECLS
  333. #endif