]> git.saurik.com Git - apple/objc4.git/blobdiff - runtime/objc-class.h
objc4-222.tar.gz
[apple/objc4.git] / runtime / objc-class.h
index 7d3be02b5002701ba177f45ba6c73d2b279c2b1e..b1b61c34ab1402bb782e58f9923782bd17cfc577 100644 (file)
@@ -47,8 +47,8 @@ struct objc_class {
        struct objc_cache *cache;
        struct objc_protocol_list *protocols;
 };
-#define CLS_GETINFO(cls,infomask)      ((cls)->info & infomask)
-#define CLS_SETINFO(cls,infomask)      ((cls)->info |= infomask)
+#define CLS_GETINFO(cls,infomask)      ((cls)->info & (infomask))
+#define CLS_SETINFO(cls,infomask)      ((cls)->info |= (infomask))
 
 #define CLS_CLASS              0x1L
 #define CLS_META               0x2L
@@ -62,6 +62,51 @@ struct objc_class {
 // the JavaBridge constructs classes with these markers
 #define CLS_JAVA_HYBRID                0x200L
 #define CLS_JAVA_CLASS         0x400L
+// thread-safe +initialize
+#define CLS_INITIALIZING       0x800
+
+/*
+ * (true as of 2001-9-24)
+ * Thread-safety note: changes to these flags are not atomic, so 
+ * the only thing preventing lost updates is the timing of the changes.
+ *
+ * As long as the following are isolated from each other for any one class, 
+ * nearly all flag updates will be safe:
+ * - compile-time
+ * - loading in one thread (not including +load) without messaging
+ * - initializing in one thread with messaging from that thread only
+ * - multi-threaded messaging with method caching
+ *
+ * The current code doesn't protect loading yet.
+ *
+ * Times when the flags may change:
+ * CLS_CLASS: compile-time, hand-built classes
+ * CLS_META: compile time, hand-built classes
+ * CLS_INITIALIZED: initialize
+ * CLS_POSING: unsafe, but posing has other thread-safety problems
+ * CLS_MAPPED: compile-time
+ * CLS_FLUSH_CACHE: messaging
+ * CLS_GROW_CACHE: messaging
+ *   FLUSH_CACHE and GROW_CACHE are protected from each other by the 
+ *   cacheUpdateLock.
+ * CLS_NEED_BIND: load, initialize
+ * CLS_METHOD_ARRAY: load
+ * CLS_JAVA_HYBRID: hand-built classes
+ * CLS_JAVA_CLASS: hand-built classes, initialize
+ * CLS_INITIALIZING: initialize
+ *
+ * The only unsafe updates are:
+ * - posing (unsafe anyway)
+ * - hand-built classes (including JavaBridge classes)
+ *   There is a short time between objc_addClass inserts the new class 
+ *   into the class_hash and the builder setting the right flags. 
+ *   A thread looking at the class_hash could send a message to the class 
+ *   and trigger initialization, and the changes to the initialization 
+ *   flags and the hand-adjusted flags could collide. 
+ *   Solution: don't do that. 
+ */
+
+
 /* 
  *     Category Template
  */
@@ -74,24 +119,27 @@ struct objc_category {
        struct objc_method_list *class_methods;
        struct objc_protocol_list *protocols;
 };
+
 /* 
  *     Instance Variable Template
  */
 typedef struct objc_ivar *Ivar;
 
-struct objc_ivar_list {
-       int ivar_count;
+struct objc_ivar {
+       char *ivar_name;
+       char *ivar_type;
+       int ivar_offset;
 #ifdef __alpha__
        int space;
 #endif
-       struct objc_ivar {
-               char *ivar_name;
-               char *ivar_type;
-               int ivar_offset;
+};
+
+struct objc_ivar_list {
+       int ivar_count;
 #ifdef __alpha__
-               int space;
+       int space;
 #endif
-       } ivar_list[1];                 /* variable length structure */
+       struct objc_ivar ivar_list[1];          /* variable length structure */
 };
 
 OBJC_EXPORT Ivar object_setInstanceVariable(id, const char *name, void *);
@@ -102,6 +150,12 @@ OBJC_EXPORT Ivar object_getInstanceVariable(id, const char *name, void **);
  */
 typedef struct objc_method *Method;
 
+struct objc_method {
+       SEL method_name;
+       char *method_types;
+       IMP method_imp;
+};
+
 struct objc_method_list {
        struct objc_method_list *obsolete;
 
@@ -109,11 +163,7 @@ struct objc_method_list {
 #ifdef __alpha__
        int space;
 #endif
-       struct objc_method {
-               SEL method_name;
-               char *method_types;
-                IMP method_imp;
-       } method_list[1];               /* variable length structure */
+       struct objc_method method_list[1];      /* variable length structure */
 };
 
 /* Protocol support */
@@ -160,6 +210,7 @@ typedef struct objc_cache * Cache;
 #define CACHE_BUCKET_NAME(B)  ((B)->method_name)
 #define CACHE_BUCKET_IMP(B)   ((B)->method_imp)
 #define CACHE_BUCKET_VALID(B) (B)
+#define CACHE_HASH(sel, mask) (((uarith_t)(sel)>>2) & (mask))
 struct objc_cache {
        unsigned int mask;            /* total = mask + 1 */
        unsigned int occupied;        
@@ -185,7 +236,6 @@ OBJC_EXPORT Class class_poseAs(Class imposter, Class original);
 OBJC_EXPORT unsigned method_getNumberOfArguments(Method);
 OBJC_EXPORT unsigned method_getSizeOfArguments(Method);
 OBJC_EXPORT unsigned method_getArgumentInfo(Method m, int arg, const char **type, int *offset);
-OBJC_EXPORT const char * NSModulePathForClass (Class aClass);
 
 // usage for nextMethodList
 //