]> git.saurik.com Git - apple/objc4.git/blobdiff - runtime/objc-private.h
objc4-646.tar.gz
[apple/objc4.git] / runtime / objc-private.h
index fd63f76c318b2c8eb4ed4eaf251083e0324835f5..055fc728eb550b691975659c124120573be7e659 100644 (file)
 #ifndef _OBJC_PRIVATE_H_
 #define _OBJC_PRIVATE_H_
 
-#include "objc-os.h"
-
-#include "objc.h"
-#include "runtime.h"
-#include "maptable.h"
-#include "hashtable2.h"
-#include "objc-api.h"
 #include "objc-config.h"
-#include "objc-rtp.h"
-#include "objc-references.h"
-#include "objc-initialize.h"
-#include "objc-loadmethod.h"
-#include "objc-internal.h"
 
-#include "objc-auto.h"
+/* Isolate ourselves from the definitions of id and Class in the compiler 
+ * and public headers.
+ */
 
-#define __APPLE_API_PRIVATE
-#include "objc-gdb.h"
-#undef __APPLE_API_PRIVATE
+#ifdef _OBJC_OBJC_H_
+#error include objc-private.h before other headers
+#endif
 
-/* Do not include message.h here. */
-/* #include "message.h" */
+#define OBJC_TYPES_DEFINED 1
+#define OBJC_OLD_DISPATCH_PROTOTYPES 0
 
+#include <cstddef>  // for nullptr_t
+#include <stdint.h>
+#include <assert.h>
 
-__BEGIN_DECLS
+struct objc_class;
+struct objc_object;
 
-#if defined(OBJC_NO_GC) != defined(NO_GC) 
-#   error OBJC_NO_GC and NO_GC inconsistent
-#endif
+typedef struct objc_class *Class;
+typedef struct objc_object *id;
 
-#ifndef NO_GC
-#   include <auto_zone.h>
-    extern BOOL UseGC;  // equivalent to calling objc_collecting_enabled()
-    extern auto_zone_t *gc_zone;  // the GC zone, or NULL if no GC
-    extern void objc_addRegisteredClass(Class c);
-    extern void objc_removeRegisteredClass(Class c);
-#else
-#   define UseGC NO
-#   define gc_zone NULL
-#   define objc_assign_ivar_internal objc_assign_ivar
-#   define objc_addRegisteredClass(c) do {} while(0)
-#   define objc_removeRegisteredClass(c) do {} while(0)
-    /* Uses of the following must be protected with UseGC. */
-    extern id gc_unsupported_dont_call();
-#   define auto_zone_allocate_object gc_unsupported_dont_call
-#   define auto_zone_retain gc_unsupported_dont_call
-#   define auto_zone_release gc_unsupported_dont_call
-#   define auto_zone_is_valid_pointer gc_unsupported_dont_call
-#   define auto_zone_write_barrier_memmove gc_unsupported_dont_call
-#   define AUTO_OBJECT_SCANNED 0
-#endif
+namespace {
+    class SideTable;
+};
 
-struct old_category;
-struct old_method_list;
-typedef struct {
-    IMP imp;
-    SEL sel;
-} message_ref;
 
-#if __OBJC2__
+union isa_t 
+{
+    isa_t() { }
+    isa_t(uintptr_t value) : bits(value) { }
+
+    Class cls;
+    uintptr_t bits;
+
+#if SUPPORT_NONPOINTER_ISA
+
+    // extra_rc must be the MSB-most field (so it matches carry/overflow flags)
+    // indexed must be the LSB (fixme or get rid of it)
+    // shiftcls must occupy the same bits that a real class pointer would
+    // bits + RC_ONE is equivalent to extra_rc + 1
+    // RC_HALF is the high bit of extra_rc (i.e. half of its range)
+
+    // future expansion:
+    // uintptr_t fast_rr : 1;     // no r/r overrides
+    // uintptr_t lock : 2;        // lock for atomic property, @synch
+    // uintptr_t extraBytes : 1;  // allocated with extra bytes
+
+# if __arm64__
+#   define ISA_MASK        0x00000001fffffff8ULL
+#   define ISA_MAGIC_MASK  0x000003fe00000001ULL
+#   define ISA_MAGIC_VALUE 0x000001a400000001ULL
+    struct {
+        uintptr_t indexed           : 1;
+        uintptr_t has_assoc         : 1;
+        uintptr_t has_cxx_dtor      : 1;
+        uintptr_t shiftcls          : 30; // MACH_VM_MAX_ADDRESS 0x1a0000000
+        uintptr_t magic             : 9;
+        uintptr_t weakly_referenced : 1;
+        uintptr_t deallocating      : 1;
+        uintptr_t has_sidetable_rc  : 1;
+        uintptr_t extra_rc          : 19;
+#       define RC_ONE   (1ULL<<45)
+#       define RC_HALF  (1ULL<<18)
+    };
+
+# elif __x86_64__
+#   define ISA_MASK        0x00007ffffffffff8ULL
+#   define ISA_MAGIC_MASK  0x0000000000000001ULL
+#   define ISA_MAGIC_VALUE 0x0000000000000001ULL
+    struct {
+        uintptr_t indexed           : 1;
+        uintptr_t has_assoc         : 1;
+        uintptr_t has_cxx_dtor      : 1;
+        uintptr_t shiftcls          : 44; // MACH_VM_MAX_ADDRESS 0x7fffffe00000
+        uintptr_t weakly_referenced : 1;
+        uintptr_t deallocating      : 1;
+        uintptr_t has_sidetable_rc  : 1;
+        uintptr_t extra_rc          : 14;
+#       define RC_ONE   (1ULL<<50)
+#       define RC_HALF  (1ULL<<13)
+    };
+
+# else
+    // Available bits in isa field are architecture-specific.
+#   error unknown architecture
+# endif
+
+// SUPPORT_NONPOINTER_ISA
+#endif
+
+};
 
-typedef struct objc_module *Module;
-typedef struct objc_cache *Cache;
 
+struct objc_object {
+private:
+    isa_t isa;
+
+public:
+
+    // ISA() assumes this is NOT a tagged pointer object
+    Class ISA();
+
+    // getIsa() allows this to be a tagged pointer object
+    Class getIsa();
+
+    // initIsa() should be used to init the isa of new objects only.
+    // If this object already has an isa, use changeIsa() for correctness.
+    // initInstanceIsa(): objects with no custom RR/AWZ
+    // initClassIsa(): class objects
+    // initProtocolIsa(): protocol objects
+    // initIsa(): other objects
+    void initIsa(Class cls /*indexed=false*/);
+    void initClassIsa(Class cls /*indexed=maybe*/);
+    void initProtocolIsa(Class cls /*indexed=maybe*/);
+    void initInstanceIsa(Class cls, bool hasCxxDtor);
+
+    // changeIsa() should be used to change the isa of existing objects.
+    // If this is a new object, use initIsa() for performance.
+    Class changeIsa(Class newCls);
+
+    bool hasIndexedIsa();
+    bool isTaggedPointer();
+    bool isClass();
+
+    // object may have associated objects?
+    bool hasAssociatedObjects();
+    void setHasAssociatedObjects();
+
+    // object may be weakly referenced?
+    bool isWeaklyReferenced();
+    void setWeaklyReferenced_nolock();
+
+    // object may have -.cxx_destruct implementation?
+    bool hasCxxDtor();
+
+    // Optimized calls to retain/release methods
+    id retain();
+    void release();
+    id autorelease();
+
+    // Implementations of retain/release methods
+    id rootRetain();
+    bool rootRelease();
+    id rootAutorelease();
+    bool rootTryRetain();
+    bool rootReleaseShouldDealloc();
+    uintptr_t rootRetainCount();
+
+    // Implementation of dealloc methods
+    bool rootIsDeallocating();
+    void clearDeallocating();
+    void rootDealloc();
+
+private:
+    void initIsa(Class newCls, bool indexed, bool hasCxxDtor);
+
+    // Slow paths for inline control
+    id rootAutorelease2();
+    bool overrelease_error();
+
+#if SUPPORT_NONPOINTER_ISA
+    // Unified retain count manipulation for nonpointer isa
+    id rootRetain(bool tryRetain, bool handleOverflow);
+    bool rootRelease(bool performDealloc, bool handleUnderflow);
+    id rootRetain_overflow(bool tryRetain);
+    bool rootRelease_underflow(bool performDealloc);
+
+    void clearDeallocating_weak();
+
+    // Side table retain count overflow for nonpointer isa
+    void sidetable_lock();
+    void sidetable_unlock();
+
+    void sidetable_moveExtraRC_nolock(size_t extra_rc, bool isDeallocating, bool weaklyReferenced);
+    bool sidetable_addExtraRC_nolock(size_t delta_rc);
+    bool sidetable_subExtraRC_nolock(size_t delta_rc);
+    size_t sidetable_getExtraRC_nolock();
 #endif
 
+    // Side-table-only retain count
+    bool sidetable_isDeallocating();
+    void sidetable_clearDeallocating();
 
-#if OLD
-
-struct old_class {
-    struct old_class *isa;
-    struct old_class *super_class;
-    const char *name;
-    long version;
-    long info;
-    long instance_size;
-    struct old_ivar_list *ivars;
-    struct old_method_list **methodLists;
-    Cache cache;
-    struct old_protocol_list *protocols;
-    // CLS_EXT only
-    const char *ivar_layout;
-    struct old_class_ext *ext;
-};
+    bool sidetable_isWeaklyReferenced();
+    void sidetable_setWeaklyReferenced_nolock();
 
-struct old_class_ext {
-    uint32_t size;
-    const char *weak_ivar_layout;
-    struct objc_property_list **propertyLists;
-};
+    id sidetable_retain();
+    id sidetable_retain_slow(SideTable *table);
 
-struct old_category {
-    char *category_name;
-    char *class_name;
-    struct old_method_list *instance_methods;
-    struct old_method_list *class_methods;
-    struct old_protocol_list *protocols;
-    uint32_t size;
-    struct objc_property_list *instance_properties;
-};
+    bool sidetable_release(bool performDealloc = true);
+    bool sidetable_release_slow(SideTable *table, bool performDealloc = true);
 
-struct old_ivar {
-    char *ivar_name;
-    char *ivar_type;
-    int ivar_offset;
-#ifdef __LP64__
-    int space;
-#endif
-};
+    bool sidetable_tryRetain();
 
-struct old_ivar_list {
-    int ivar_count;
-#ifdef __LP64__
-    int space;
+    uintptr_t sidetable_retainCount();
+#if !NDEBUG
+    bool sidetable_present();
 #endif
-    /* variable length structure */
-    struct old_ivar ivar_list[1];
 };
 
 
-struct old_method {
-    SEL method_name;
-    char *method_types;
-    IMP method_imp;
-};
+#if __OBJC2__
+typedef struct method_t *Method;
+typedef struct ivar_t *Ivar;
+typedef struct category_t *Category;
+typedef struct property_t *objc_property_t;
+#else
+typedef struct old_method *Method;
+typedef struct old_ivar *Ivar;
+typedef struct old_category *Category;
+typedef struct old_property *objc_property_t;
+#endif
 
-struct old_method_list {
-    struct old_method_list *obsolete;
+// Public headers
 
-    int method_count;
-#ifdef __LP64__
-    int space;
-#endif
-    /* variable length structure */
-    struct old_method method_list[1];
-};
+#include "objc.h"
+#include "runtime.h"
+#include "objc-os.h"
+#include "objc-abi.h"
+#include "objc-api.h"
+#include "objc-auto.h"
+#include "objc-config.h"
+#include "objc-internal.h"
+#include "maptable.h"
+#include "hashtable2.h"
 
-struct old_protocol {
-    Class isa;
-    const char *protocol_name;
-    struct old_protocol_list *protocol_list;
-    struct objc_method_description_list *instance_methods;
-    struct objc_method_description_list *class_methods;
-};
+/* Do not include message.h here. */
+/* #include "message.h" */
 
-struct old_protocol_list {
-    struct old_protocol_list *next;
-    long count;
-    struct old_protocol *list[1];
-};
+#define __APPLE_API_PRIVATE
+#include "objc-gdb.h"
+#undef __APPLE_API_PRIVATE
 
-struct old_protocol_ext {
-    uint32_t size;
-    struct objc_method_description_list *optional_instance_methods;
-    struct objc_method_description_list *optional_class_methods;
-    struct objc_property_list *instance_properties;
-};
 
+// Private headers
+
+#if __OBJC2__
+#include "objc-runtime-new.h"
+#else
+#include "objc-runtime-old.h"
 #endif
 
-typedef objc_property_t Property;
+#include "objc-references.h"
+#include "objc-initialize.h"
+#include "objc-loadmethod.h"
 
-struct objc_property {
-    const char *name;
-    const char *attributes;
-};
 
-struct objc_property_list {
-    uint32_t entsize;
-    uint32_t count;
-    struct objc_property first;
-};
+__BEGIN_DECLS
 
-typedef struct {
-    uint32_t version; // currently 0
-    uint32_t flags;
-} objc_image_info;
 
-// masks for objc_image_info.flags
-#define OBJC_IMAGE_IS_REPLACEMENT (1<<0)
-#define OBJC_IMAGE_SUPPORTS_GC (1<<1)
-#define OBJC_IMAGE_REQUIRES_GC (1<<2)
-#define OBJC_IMAGE_OPTIMIZED_BY_DYLD (1<<3)
+#if (defined(OBJC_NO_GC) && SUPPORT_GC)  ||  \
+    (!defined(OBJC_NO_GC) && !SUPPORT_GC)
+#   error OBJC_NO_GC and SUPPORT_GC inconsistent
+#endif
+
+#if SUPPORT_GC
+#   include <auto_zone.h>
+    // PRIVATE_EXTERN is needed to help the compiler know "how" extern these are
+    PRIVATE_EXTERN extern int8_t UseGC;          // equivalent to calling objc_collecting_enabled()
+    PRIVATE_EXTERN extern auto_zone_t *gc_zone;  // the GC zone, or NULL if no GC
+    extern void objc_addRegisteredClass(Class c);
+    extern void objc_removeRegisteredClass(Class c);
+#else
+#   define UseGC NO
+#   define gc_zone NULL
+#   define objc_addRegisteredClass(c) do {} while(0)
+#   define objc_removeRegisteredClass(c) do {} while(0)
+    /* Uses of the following must be protected with UseGC. */
+    extern id gc_unsupported_dont_call();
+#   define auto_zone_allocate_object gc_unsupported_dont_call
+#   define auto_zone_retain gc_unsupported_dont_call
+#   define auto_zone_release gc_unsupported_dont_call
+#   define auto_zone_is_valid_pointer gc_unsupported_dont_call
+#   define auto_zone_write_barrier_memmove gc_unsupported_dont_call
+#   define AUTO_OBJECT_SCANNED 0
+#endif
 
 
 #define _objcHeaderIsReplacement(h)  ((h)->info  &&  ((h)->info->flags & OBJC_IMAGE_IS_REPLACEMENT))
@@ -221,7 +316,7 @@ typedef struct {
    Do fix up selector refs (@selector points to them)
    Do fix up class refs (@class and objc_msgSend points to them)
    Do fix up protocols (@protocol points to them)
-   Do fix up super_class pointers in classes ([super ...] points to them)
+   Do fix up superclass pointers in classes ([super ...] points to them)
    Future: do load new classes?
    Future: do load new categories?
    Future: do insert new methods on existing classes?
@@ -248,58 +343,54 @@ typedef struct {
 
 typedef struct _header_info {
     struct _header_info *next;
-    const headerType *  mhdr;
+    const headerType *mhdr;
+    const objc_image_info *info;
+    const char *fname;  // same as Dl_info.dli_fname
+    bool loaded;
+    bool inSharedCache;
+    bool allClassesRealized;
+
+    // Do not add fields without editing ObjCModernAbstraction.hpp
+
+#if !__OBJC2__
+    struct old_protocol **proto_refs;
     struct objc_module *mod_ptr;
     size_t              mod_count;
-    const objc_image_info *info;
-    BOOL                allClassesRealized;
-    os_header_info      os;
+# if TARGET_OS_WIN32
+    struct objc_module **modules;
+    size_t moduleCount;
+    struct old_protocol **protocols;
+    size_t protocolCount;
+    void *imageinfo;
+    size_t imageinfoBytes;
+    SEL *selrefs;
+    size_t selrefCount;
+    struct objc_class **clsrefs;
+    size_t clsrefCount;    
+    TCHAR *moduleName;
+# endif
+#endif
 } header_info;
 
 extern header_info *FirstHeader;
 extern header_info *LastHeader;
 extern int HeaderCount;
 
-extern void _objc_appendHeader(header_info *hi);
-extern void _objc_removeHeader(header_info *hi);
-extern const char *_nameForHeader(const headerType*);
+extern uint32_t AppSDKVersion;  // X.Y.Z is 0xXXXXYYZZ
 
-extern objc_image_info *_getObjcImageInfo(const headerType *head, ptrdiff_t slide, size_t *size);
-extern const char *_getObjcHeaderName(const headerType *head);
-extern ptrdiff_t _getImageSlide(const headerType *header);
+extern void appendHeader(header_info *hi);
+extern void removeHeader(header_info *hi);
 
-
-extern Module _getObjcModules(const header_info *hi, size_t *count);
-extern SEL *_getObjcSelectorRefs(const header_info *hi, size_t *count);
+extern objc_image_info *_getObjcImageInfo(const headerType *head, size_t *size);
 extern BOOL _hasObjcContents(const header_info *hi);
-#if !__OBJC2__
-extern struct old_protocol **_getObjcProtocols(const header_info *head, size_t *count);
-extern struct old_class **_getObjcClassRefs(const header_info *hi, size_t *count);
-extern const char *_getObjcClassNames(const header_info *hi, size_t *size);
-#endif
-
-#if __OBJC2__
-extern SEL *_getObjc2SelectorRefs(const header_info *hi, size_t *count);
-extern message_ref *_getObjc2MessageRefs(const header_info *hi, size_t *count);extern struct class_t **_getObjc2ClassRefs(const header_info *hi, size_t *count);
-extern struct class_t **_getObjc2SuperRefs(const header_info *hi, size_t *count);
-extern struct class_t **_getObjc2ClassList(const header_info *hi, size_t *count);
-extern struct class_t **_getObjc2NonlazyClassList(const header_info *hi, size_t *count);
-extern struct category_t **_getObjc2CategoryList(const header_info *hi, size_t *count);
-extern struct category_t **_getObjc2NonlazyCategoryList(const header_info *hi, size_t *count);
-extern struct protocol_t **_getObjc2ProtocolList(const header_info *head, size_t *count);
-extern struct protocol_t **_getObjc2ProtocolRefs(const header_info *head, size_t *count);
-#endif
-
-#define END_OF_METHODS_LIST ((struct old_method_list*)-1)
 
 
 /* selectors */
-extern void sel_init(BOOL gc);
+extern void sel_init(BOOL gc, size_t selrefCount);
 extern SEL sel_registerNameNoLock(const char *str, BOOL copy);
 extern void sel_lock(void);
 extern void sel_unlock(void);
 extern BOOL sel_preoptimizationValid(const header_info *hi);
-extern void disableSelectorPreoptimization(void);
 
 extern SEL SEL_load;
 extern SEL SEL_initialize;
@@ -310,8 +401,35 @@ extern SEL SEL_cxx_destruct;
 extern SEL SEL_retain;
 extern SEL SEL_release;
 extern SEL SEL_autorelease;
+extern SEL SEL_retainCount;
+extern SEL SEL_alloc;
+extern SEL SEL_allocWithZone;
+extern SEL SEL_dealloc;
 extern SEL SEL_copy;
+extern SEL SEL_new;
 extern SEL SEL_finalize;
+extern SEL SEL_forwardInvocation;
+extern SEL SEL_tryRetain;
+extern SEL SEL_isDeallocating;
+extern SEL SEL_retainWeakReference;
+extern SEL SEL_allowsWeakReference;
+
+/* preoptimization */
+extern void preopt_init(void);
+extern void disableSharedCacheOptimizations(void);
+extern bool isPreoptimized(void);
+extern header_info *preoptimizedHinfoForHeader(const headerType *mhdr);
+
+#if SUPPORT_PREOPT  &&  __cplusplus
+#include <objc-shared-cache.h>
+using objc_selopt_t = const objc_opt::objc_selopt_t;
+#else
+struct objc_selopt_t;
+#endif
+
+extern objc_selopt_t *preoptimizedSelectors(void);
+extern Class getPreoptimizedClass(const char *name);
+extern Class* copyPreoptimizedClasses(const char *name, int *outCount);
 
 
 /* optional malloc zone for runtime data */
@@ -321,63 +439,66 @@ extern void *_calloc_internal(size_t count, size_t size);
 extern void *_realloc_internal(void *ptr, size_t size);
 extern char *_strdup_internal(const char *str);
 extern char *_strdupcat_internal(const char *s1, const char *s2);
+extern uint8_t *_ustrdup_internal(const uint8_t *str);
 extern void *_memdup_internal(const void *mem, size_t size);
 extern void _free_internal(void *ptr);
+extern size_t _malloc_size_internal(void *ptr);
 
 extern Class _calloc_class(size_t size);
 
-#if !__OBJC2__
-extern Class objc_getOrigClass (const char *name);
-extern IMP lookupNamedMethodInMethodList(struct old_method_list *mlist, const char *meth_name);
-extern void _objc_insertMethods(struct old_class *cls, struct old_method_list *mlist, struct old_category *cat);
-extern void _objc_removeMethods(struct old_class *cls, struct old_method_list *mlist);
-extern void _objc_flush_caches (Class cls);
-extern void _class_addProperties(struct old_class *cls, struct objc_property_list *additions);
-extern void change_class_references(struct old_class *imposter, struct old_class *original, struct old_class *copy, BOOL changeSuperRefs);
-extern void flush_marked_caches(void);
-extern void set_superclass(struct old_class *cls, struct old_class *supercls);
-#endif
+/* method lookup */
+extern IMP lookUpImpOrNil(Class, SEL, id obj, bool initialize, bool cache, bool resolver);
+extern IMP lookUpImpOrForward(Class, SEL, id obj, bool initialize, bool cache, bool resolver);
 
-extern IMP lookUpMethod(Class, SEL, BOOL initialize, BOOL cache);
-extern void lockForMethodLookup(void);
-extern void unlockForMethodLookup(void);
-extern IMP prepareForMethodLookup(Class cls, SEL sel, BOOL initialize);
+extern IMP lookupMethodInClassAndLoadCache(Class cls, SEL sel);
+extern BOOL class_respondsToSelector_inst(Class cls, SEL sel, id inst);
 
-extern IMP _cache_getImp(Class cls, SEL sel);
-extern Method _cache_getMethod(Class cls, SEL sel, IMP objc_msgForward_internal_imp);
+extern bool objcMsgLogEnabled;
+extern bool logMessageSend(bool isClassMethod,
+                    const char *objectsClass,
+                    const char *implementingClass,
+                    SEL selector);
 
 /* message dispatcher */
-extern IMP _class_lookupMethodAndLoadCache(Class, SEL);
-extern id _objc_msgForward_internal(id self, SEL sel, ...);
-extern id _objc_ignored_method(id self, SEL _cmd);
+extern IMP _class_lookupMethodAndLoadCache3(id, SEL, Class);
+
+#if !OBJC_OLD_DISPATCH_PROTOTYPES
+extern void _objc_msgForward_impcache(void);
+extern void _objc_ignored_method(void);
+extern void _objc_msgSend_uncached_impcache(void);
+#else
+extern id _objc_msgForward_impcache(id, SEL, ...);
+extern id _objc_ignored_method(id, SEL, ...);
+extern id _objc_msgSend_uncached_impcache(id, SEL, ...);
+#endif
 
 /* errors */
-extern void __objc_error(id, const char *, ...) __attribute__((format (printf, 2, 3)));
+extern void __objc_error(id, const char *, ...) __attribute__((format (printf, 2, 3), noreturn));
 extern void _objc_inform(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
 extern void _objc_inform_on_crash(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
 extern void _objc_inform_now_and_on_crash(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
-extern void _objc_warn_deprecated(const char *oldname, const char *newname) __attribute__((noinline));
-extern void _objc_error(id, const char *, va_list);
+extern void _objc_inform_deprecated(const char *oldname, const char *newname) __attribute__((noinline));
 extern void inform_duplicate(const char *name, Class oldCls, Class cls);
+extern bool crashlog_header_name(header_info *hi);
+extern bool crashlog_header_name_string(const char *name);
 
 /* magic */
 extern Class _objc_getFreedObjectClass (void);
-#ifndef OBJC_INSTRUMENTED
-extern const struct objc_cache _objc_empty_cache;
-#else
-extern struct objc_cache _objc_empty_cache;
-#endif
-#if __OBJC2__
-extern IMP _objc_empty_vtable[128];
-#endif
 
 /* map table additions */
 extern void *NXMapKeyCopyingInsert(NXMapTable *table, const void *key, const void *value);
 extern void *NXMapKeyFreeingRemove(NXMapTable *table, const void *key);
 
+/* hash table additions */
+extern unsigned _NXHashCapacity(NXHashTable *table);
+extern void _NXHashRehashToCapacity(NXHashTable *table, unsigned newCapacity);
+
+/* property attribute parsing */
+extern const char *copyPropertyAttributeString(const objc_property_attribute_t *attrs, unsigned int count);
+extern objc_property_attribute_t *copyPropertyAttributeList(const char *attrs, unsigned int *outCount);
+extern char *copyPropertyAttributeValue(const char *attrs, const char *name);
+
 /* locking */
-/* Every lock used anywhere must be declared here. 
- * Locks not declared here may cause gdb deadlocks. */
 extern void lock_init(void);
 extern rwlock_t selLock;
 extern mutex_t cacheUpdateLock;
@@ -389,17 +510,9 @@ extern mutex_t classLock;
 extern mutex_t methodListLock;
 #endif
 
-/* Debugger mode for gdb */
-#define DEBUGGER_OFF 0
-#define DEBUGGER_PARTIAL 1
-#define DEBUGGER_FULL 2
-extern int startDebuggerMode(void);
-extern void endDebuggerMode(void);
-
+/* Lock debugging */
 #if defined(NDEBUG)  ||  TARGET_OS_WIN32
 
-#define _destroyLockList(x)           do { } while (0)
-
 #define mutex_lock(m)             _mutex_lock_nodebug(m)
 #define mutex_try_lock(m)         _mutex_try_lock_nodebug(m)
 #define mutex_unlock(m)           _mutex_unlock_nodebug(m)
@@ -431,9 +544,6 @@ extern void endDebuggerMode(void);
 
 #else
 
-struct _objc_lock_list;
-extern void _destroyLockList(struct _objc_lock_list *locks);
-
 extern int _mutex_lock_debug(mutex_t *lock, const char *name);
 extern int _mutex_try_lock_debug(mutex_t *lock, const char *name);
 extern int _mutex_unlock_debug(mutex_t *lock, const char *name);
@@ -501,22 +611,51 @@ extern void _rwlock_assert_unlocked_debug(rwlock_t *l, const char *name);
     } while (0)
 
 
-extern NXHashTable *class_hash;
+/* ignored selector support */
+
+/* Non-GC: no ignored selectors
+   GC (i386 Mac): some selectors ignored, remapped to kIgnore
+   GC (others): some selectors ignored, but not remapped 
+*/
 
-#if !TARGET_OS_WIN32
-/* nil handler object */
-extern id _objc_nilReceiver;
-extern id _objc_setNilReceiver(id newNilReceiver);
-extern id _objc_getNilReceiver(void);
+static inline int ignoreSelector(SEL sel)
+{
+#if !SUPPORT_GC
+    return NO;
+#elif SUPPORT_IGNORED_SELECTOR_CONSTANT
+    return UseGC  &&  sel == (SEL)kIgnore;
+#else
+    return UseGC  &&  
+        (sel == @selector(retain)       ||  
+         sel == @selector(release)      ||  
+         sel == @selector(autorelease)  ||  
+         sel == @selector(retainCount)  ||  
+         sel == @selector(dealloc));
 #endif
+}
 
-/* forward handler functions */
-extern void *_objc_forward_handler;
-extern void *_objc_forward_stret_handler;
+static inline int ignoreSelectorNamed(const char *sel)
+{
+#if !SUPPORT_GC
+    return NO;
+#else
+    // release retain retainCount dealloc autorelease
+    return (UseGC &&
+            (  (sel[0] == 'r' && sel[1] == 'e' &&
+                (strcmp(&sel[2], "lease") == 0 || 
+                 strcmp(&sel[2], "tain") == 0 ||
+                 strcmp(&sel[2], "tainCount") == 0 ))
+               ||
+               (strcmp(sel, "dealloc") == 0)
+               || 
+               (sel[0] == 'a' && sel[1] == 'u' && 
+                strcmp(&sel[2], "torelease") == 0)));
+#endif
+}
 
-/* GC and RTP startup */
-extern void gc_init(BOOL on);
-extern void rtp_init(void);
+/* GC startup */
+extern void gc_init(BOOL wantsGC);
+extern void gc_init2(void);
 
 /* Exceptions */
 struct alt_handler_list;
@@ -531,15 +670,23 @@ extern void _destroyAltHandlerList(struct alt_handler_list *list);
 extern void gdb_objc_class_changed(Class cls, unsigned long changes, const char *classname)
     __attribute__((noinline));
 
+#if SUPPORT_GC
+
 /* Write barrier implementations */
-extern id objc_assign_strongCast_non_gc(id value, id *dest);
-extern id objc_assign_global_non_gc(id value, id *dest);
-extern id objc_assign_ivar_non_gc(id value, id dest, ptrdiff_t offset);
-extern id objc_assign_strongCast_gc(id val, id *dest);
-extern id objc_assign_global_gc(id val, id *dest);
-extern id objc_assign_ivar_gc(id value, id dest, ptrdiff_t offset);
+extern id objc_getAssociatedObject_non_gc(id object, const void *key);
+extern void objc_setAssociatedObject_non_gc(id object, const void *key, id value, objc_AssociationPolicy policy);
+
+extern id objc_getAssociatedObject_gc(id object, const void *key);
+extern void objc_setAssociatedObject_gc(id object, const void *key, id value, objc_AssociationPolicy policy);
 
-#ifndef NO_GC
+/* xrefs */
+extern objc_xref_t _object_addExternalReference_non_gc(id obj, objc_xref_t type);
+extern id _object_readExternalReference_non_gc(objc_xref_t ref);
+extern void _object_removeExternalReference_non_gc(objc_xref_t ref);
+
+extern objc_xref_t _object_addExternalReference_gc(id obj, objc_xref_t type);
+extern id _object_readExternalReference_gc(objc_xref_t ref);
+extern void _object_removeExternalReference_gc(objc_xref_t ref);
 
 /* GC weak reference fixup. */
 extern void gc_fixup_weakreferences(id newObject, id oldObject);
@@ -548,95 +695,21 @@ extern void gc_fixup_weakreferences(id newObject, id oldObject);
 extern void gc_register_datasegment(uintptr_t base, size_t size);
 extern void gc_unregister_datasegment(uintptr_t base, size_t size);
 
-/*
-    objc_assign_ivar, objc_assign_global, and objc_assign_strongCast MUST NOT be called directly
-    from inside libobjc. They live in the data segment, and must be called through the
-    following pointer(s) for libobjc to exist in the shared cache.
+/* objc_dumpHeap implementation */
+extern BOOL _objc_dumpHeap(auto_zone_t *zone, const char *filename);
 
-    Note: If we build with GC enabled, gcc will emit calls to the original functions, which will break this.
-*/
-
-extern id (*objc_assign_ivar_internal)(id, id, ptrdiff_t);
-
-#endif
-
-/* Code modification */
-extern size_t objc_branch_size(void *entry, void *target);
-extern size_t objc_write_branch(void *entry, void *target);
-extern size_t objc_cond_branch_size(void *entry, void *target, unsigned cond);
-extern size_t objc_write_cond_branch(void *entry, void *target, unsigned cond);
-#if defined(__ppc__)  ||  defined(__ppc64__)
-#define COND_ALWAYS 0x02800000  /* BO=10100, BI=00000 */
-#define COND_NE     0x00820000  /* BO=00100, BI=00010 */
-#elif defined(__i386__) || defined(__x86_64__)
-#define COND_ALWAYS 0xE9  /* JMP rel32 */
-#define COND_NE     0x85  /* JNE rel32  (0F 85) */
-#endif
-
-
-/* Thread-safe info field */
-#if !__OBJC2__
-extern void _class_setInfo(Class cls, long set);
-extern void _class_clearInfo(Class cls, long clear);
-extern void _class_changeInfo(Class cls, long set, long clear);
-#endif
-
-
-#if !defined(SEG_OBJC)
-#define SEG_OBJC        "__OBJC"        /* objective-C runtime segment */
 #endif
 
 
 // Settings from environment variables
-#if NO_ENVIRON
-#   define ENV(x) enum { x = 0 }
-#else
-#   define ENV(x) extern int x
-#endif
-ENV(PrintImages);               // env OBJC_PRINT_IMAGES
-ENV(PrintLoading);              // env OBJC_PRINT_LOAD_METHODS
-ENV(PrintInitializing);         // env OBJC_PRINT_INITIALIZE_METHODS
-ENV(PrintResolving);            // env OBJC_PRINT_RESOLVED_METHODS
-ENV(PrintConnecting);           // env OBJC_PRINT_CLASS_SETUP
-ENV(PrintProtocols);            // env OBJC_PRINT_PROTOCOL_SETUP
-ENV(PrintIvars);                // env OBJC_PRINT_IVAR_SETUP
-ENV(PrintVtables);              // env OBJC_PRINT_VTABLE_SETUP
-ENV(PrintVtableImages);         // env OBJC_PRINT_VTABLE_IMAGES
-ENV(PrintFuture);               // env OBJC_PRINT_FUTURE_CLASSES
-ENV(PrintRTP);                  // env OBJC_PRINT_RTP
-ENV(PrintGC);                   // env OBJC_PRINT_GC
-ENV(PrintPreopt);               // env OBJC_PRINT_PREOPTIMIZATION
-ENV(PrintCxxCtors);             // env OBJC_PRINT_CXX_CTORS
-ENV(PrintExceptions);           // env OBJC_PRINT_EXCEPTIONS
-ENV(PrintAltHandlers);          // env OBJC_PRINT_ALT_HANDLERS
-ENV(PrintDeprecation);          // env OBJC_PRINT_DEPRECATION_WARNINGS
-ENV(PrintReplacedMethods);      // env OBJC_PRINT_REPLACED_METHODS
-ENV(PrintCaches);               // env OBJC_PRINT_CACHE_SETUP
-ENV(UseInternalZone);           // env OBJC_USE_INTERNAL_ZONE
-
-ENV(DebugUnload);               // env OBJC_DEBUG_UNLOAD
-ENV(DebugFragileSuperclasses);  // env OBJC_DEBUG_FRAGILE_SUPERCLASSES
-ENV(DebugFinalizers);           // env OBJC_DEBUG_FINALIZERS
-ENV(DebugNilSync);              // env OBJC_DEBUG_NIL_SYNC
-
-ENV(DisableGC);                 // env OBJC_DISABLE_GC
-ENV(DisableVtables);            // env OBJC_DISABLE_VTABLES
-ENV(DisablePreopt);             // env OBJC_DISABLE_PREOPTIMIZATION
-#undef ENV
+#define OPTION(var, env, help) extern bool var;
+#include "objc-env.h"
+#undef OPTION
 
 extern void environ_init(void);
 
 extern void logReplacedMethod(const char *className, SEL s, BOOL isMeta, const char *catName, IMP oldImp, IMP newImp);
 
-
-static __inline int _objc_strcmp(const char *s1, const char *s2) {
-    char c1, c2;
-    for ( ; (c1 = *s1) == (c2 = *s2); s1++, s2++)
-        if (c1 == '\0')
-            return 0;
-    return (c1 - c2);
-}       
-
 static __inline uint32_t _objc_strhash(const char *s) {
     uint32_t hash = 0;
     for (;;) {
@@ -651,9 +724,9 @@ static __inline uint32_t _objc_strhash(const char *s) {
 // objc per-thread storage
 typedef struct {
     struct _objc_initializing_classes *initializingClasses; // for +initialize
-    struct _objc_lock_list *lockList;  // for lock debugging
     struct SyncCache *syncCache;  // for @synchronize
     struct alt_handler_list *handlerList;  // for exception alt handlers
+    char *printableNames[4];  // temporary demangled names for logging
 
     // If you add new fields here, don't forget to update 
     // _objc_pthread_destroyspecific()
@@ -663,61 +736,10 @@ typedef struct {
 extern _objc_pthread_data *_objc_fetch_pthread_data(BOOL create);
 extern void tls_init(void);
 
-
-// Class state
-#if !__OBJC2__
-#define ISCLASS(cls)           (((cls)->info & CLS_CLASS) != 0)
-#define ISMETA(cls)            (((cls)->info & CLS_META) != 0)
-#define GETMETA(cls)           (ISMETA(cls) ? (cls) : (cls)->isa)
-#endif
-
-
-// Attribute for global variables to keep them out of bss storage
-// To save one page per non-Objective-C process, variables used in 
-// the "Objective-C not used" case should not be in bss storage.
-// On Tiger, this reduces the number of touched pages for each 
-// CoreFoundation-only process from three to two. See #3857126 and #3857136.
-#define NOBSS __attribute__((section("__DATA,__data")))
-
-// cache.h
-#if TARGET_OS_WIN32
-
-#else
-static inline int isPowerOf2(unsigned long l) { return 1 == __builtin_popcountl(l); }
-#endif
-extern void flush_caches(Class cls, BOOL flush_meta);
-extern void flush_cache(Class cls);
-extern BOOL _cache_fill(Class cls, Method smt, SEL sel);
-extern void _cache_addForwardEntry(Class cls, SEL sel);
-extern void _cache_free(Cache cache);
-
-extern mutex_t cacheUpdateLock;
-
-#if !__OBJC2__
-// used by flush_caches outside objc-cache.m
-extern void _cache_flush(Class cls);
-#ifdef OBJC_INSTRUMENTED
-extern unsigned int LinearFlushCachesCount;
-extern unsigned int LinearFlushCachesVisitedCount;
-extern unsigned int MaxLinearFlushCachesVisitedCount;
-extern unsigned int NonlinearFlushCachesCount;
-extern unsigned int NonlinearFlushCachesClassCount;
-extern unsigned int NonlinearFlushCachesVisitedCount;
-extern unsigned int MaxNonlinearFlushCachesVisitedCount;
-extern unsigned int IdealFlushCachesCount;
-extern unsigned int MaxIdealFlushCachesCount;
-#endif
-#endif
-
-// objc-gdb.h
-#if !TARGET_OS_WIN32
-BOOL _objc_dumpHeap(auto_zone_t *zone, const char *filename);
-#endif
-
 // encoding.h
 extern unsigned int encoding_getNumberOfArguments(const char *typedesc);
 extern unsigned int encoding_getSizeOfArguments(const char *typedesc);
-extern unsigned int encoding_getArgumentInfo(const char *typedesc, int arg, const char **type, int *offset);
+extern unsigned int encoding_getArgumentInfo(const char *typedesc, unsigned int arg, const char **type, int *offset);
 extern void encoding_getReturnType(const char *t, char *dst, size_t dst_len);
 extern char * encoding_copyReturnType(const char *t);
 extern void encoding_getArgumentType(const char *t, unsigned int index, char *dst, size_t dst_len);
@@ -726,6 +748,13 @@ extern char *encoding_copyArgumentType(const char *t, unsigned int index);
 // sync.h
 extern void _destroySyncCache(struct SyncCache *cache);
 
+// arr
+extern void arr_init(void);
+extern id objc_autoreleaseReturnValue(id obj);
+
+// block trampolines
+extern IMP _imp_implementationWithBlockNoCopy(id block);
+
 // layout.h
 typedef struct {
     uint8_t *bits;
@@ -734,11 +763,13 @@ typedef struct {
     BOOL weak;
 } layout_bitmap;
 extern layout_bitmap layout_bitmap_create(const unsigned char *layout_string, size_t layoutStringInstanceSize, size_t instanceSize, BOOL weak);
+extern layout_bitmap layout_bitmap_create_empty(size_t instanceSize, BOOL weak);
 extern void layout_bitmap_free(layout_bitmap bits);
 extern const unsigned char *layout_string_create(layout_bitmap bits);
 extern void layout_bitmap_set_ivar(layout_bitmap bits, const char *type, size_t offset);
 extern void layout_bitmap_grow(layout_bitmap *bits, size_t newCount);
 extern void layout_bitmap_slide(layout_bitmap *bits, size_t oldPos, size_t newPos);
+extern void layout_bitmap_slide_anywhere(layout_bitmap *bits, size_t oldPos, size_t newPos);
 extern BOOL layout_bitmap_splat(layout_bitmap dst, layout_bitmap src, 
                                 size_t oldSrcInstanceSize);
 extern BOOL layout_bitmap_or(layout_bitmap dst, layout_bitmap src, const char *msg);
@@ -747,143 +778,184 @@ extern void layout_bitmap_print(layout_bitmap bits);
 
 
 // fixme runtime
-extern id look_up_class(const char *aClassName, BOOL includeUnconnected, BOOL includeClassHandler);
+extern Class look_up_class(const char *aClassName, BOOL includeUnconnected, BOOL includeClassHandler);
 extern const char *map_images(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
 extern const char *map_images_nolock(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
 extern const char * load_images(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
 extern BOOL load_images_nolock(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
 extern void unmap_image(const struct mach_header *mh, intptr_t vmaddr_slide);
-extern void unmap_image_nolock(const struct mach_header *mh, intptr_t vmaddr_slide);
+extern void unmap_image_nolock(const struct mach_header *mh);
 extern void _read_images(header_info **hList, uint32_t hCount);
 extern void prepare_load_methods(header_info *hi);
 extern void _unload_image(header_info *hi);
 extern const char ** _objc_copyClassNamesForImage(header_info *hi, unsigned int *outCount);
 
-extern Class _objc_allocateFutureClass(const char *name);
-
-
-extern Property *copyPropertyList(struct objc_property_list *plist, unsigned int *outCount);
-
 
 extern const header_info *_headerForClass(Class cls);
 
-// fixme class
-extern Property property_list_nth(const struct objc_property_list *plist, uint32_t i);
-extern size_t property_list_size(const struct objc_property_list *plist);
-
-extern Class _class_getSuperclass(Class cls);
-extern BOOL _class_getInfo(Class cls, int info);
-extern const char *_class_getName(Class cls);
-extern size_t _class_getInstanceSize(Class cls);
-extern Class _class_getMeta(Class cls);
-extern BOOL _class_isMetaClass(Class cls);
-extern Cache _class_getCache(Class cls);
-extern void _class_setCache(Class cls, Cache cache);
-extern BOOL _class_isInitializing(Class cls);
-extern BOOL _class_isInitialized(Class cls);
-extern void _class_setInitializing(Class cls);
-extern void _class_setInitialized(Class cls);
-extern Class _class_getNonMetaClass(Class cls);
-extern Method _class_getMethod(Class cls, SEL sel);
-extern Method _class_getMethodNoSuper(Class cls, SEL sel);
-extern Method _class_getMethodNoSuper_nolock(Class cls, SEL sel);
-extern BOOL _class_isLoadable(Class cls);
-extern IMP _class_getLoadMethod(Class cls);
-extern BOOL _class_hasLoadMethod(Class cls);
-extern BOOL _class_hasCxxStructorsNoSuper(Class cls);
-extern BOOL _class_shouldFinalizeOnMainThread(Class cls);
-extern void _class_setFinalizeOnMainThread(Class cls);
-extern BOOL _class_instancesHaveAssociatedObjects(Class cls);
-extern void _class_assertInstancesHaveAssociatedObjects(Class cls);
-extern BOOL _class_shouldGrowCache(Class cls);
-extern void _class_setGrowCache(Class cls, BOOL grow);
-extern Ivar _class_getVariable(Class cls, const char *name);
-
-extern id _internal_class_createInstanceFromZone(Class cls, size_t extraBytes,
-                                                 void *zone);
-extern id _internal_object_dispose(id anObject);
-
-extern Class gdb_class_getClass(Class cls);
-extern BOOL class_instancesHaveAssociatedObjects(Class cls);
-OBJC_EXPORT BOOL gdb_objc_isRuntimeLocked();
+extern Class _class_remap(Class cls);
+extern Class _class_getNonMetaClass(Class cls, id obj);
+extern Ivar _class_getVariable(Class cls, const char *name, Class *memberOf);
+extern BOOL _class_usesAutomaticRetainRelease(Class cls);
+extern uint32_t _class_getInstanceStart(Class cls);
+
+extern unsigned _class_createInstancesFromZone(Class cls, size_t extraBytes, void *zone, id *results, unsigned num_requested);
+extern id _objc_constructOrFree(id bytes, Class cls);
 
 extern const char *_category_getName(Category cat);
 extern const char *_category_getClassName(Category cat);
 extern Class _category_getClass(Category cat);
 extern IMP _category_getLoadMethod(Category cat);
 
-#if !__OBJC2__
-#define oldcls(cls) ((struct old_class *)cls)
-#define oldprotocol(proto) ((struct old_protocol *)proto)
-#define oldmethod(meth) ((struct old_method *)meth)
-#define oldcategory(cat) ((struct old_category *)cat)
-#define oldivar(ivar) ((struct old_ivar *)ivar)
-
-static inline struct old_method *_method_asOld(Method m) { return (struct old_method *)m; }
-static inline struct old_class *_class_asOld(Class cls) { return (struct old_class *)cls; }
-static inline struct old_category *_category_asOld(Category cat) { return (struct old_category *)cat; }
-
-extern void unload_class(struct old_class *cls);
-#endif
-
-extern BOOL object_cxxConstruct(id obj);
+extern id object_cxxConstructFromClass(id obj, Class cls);
 extern void object_cxxDestruct(id obj);
 
-extern Method _class_resolveMethod(Class cls, SEL sel);
-extern void log_and_fill_cache(Class cls, Class implementer, Method meth, SEL sel);
-
-#if !__OBJC2__
-#define CLS_CLASS              0x1
-#define CLS_META               0x2
-#define CLS_INITIALIZED                0x4
-#define CLS_POSING             0x8
-#define CLS_MAPPED             0x10
-#define CLS_FLUSH_CACHE                0x20
-#define CLS_GROW_CACHE         0x40
-#define CLS_NEED_BIND          0x80
-#define CLS_METHOD_ARRAY        0x100
-// the JavaBridge constructs classes with these markers
-#define CLS_JAVA_HYBRID                0x200
-#define CLS_JAVA_CLASS         0x400
-// thread-safe +initialize
-#define CLS_INITIALIZING       0x800
-// bundle unloading
-#define CLS_FROM_BUNDLE                0x1000
-// C++ ivar support
-#define CLS_HAS_CXX_STRUCTORS  0x2000
-// Lazy method list arrays
-#define CLS_NO_METHOD_ARRAY    0x4000
-// +load implementation
-#define CLS_HAS_LOAD_METHOD     0x8000
-// objc_allocateClassPair API
-#define CLS_CONSTRUCTING        0x10000
-// visibility=hidden
-#define CLS_HIDDEN              0x20000
-// GC:  class has unsafe finalize method
-#define CLS_FINALIZE_ON_MAIN_THREAD 0x40000
-// Lazy property list arrays
-#define CLS_NO_PROPERTY_ARRAY  0x80000
-// +load implementation
-#define CLS_CONNECTED           0x100000
-#define CLS_LOADED              0x200000
-// objc_allocateClassPair API
-#define CLS_CONSTRUCTED         0x400000
-// class is leaf for cache flushing
-#define CLS_LEAF                0x800000
-// class instances may have associative references
-#define CLS_INSTANCES_HAVE_ASSOCIATED_OBJECTS 0x1000000
-#endif
+extern void _class_resolveMethod(Class cls, SEL sel, id inst);
 
 #define OBJC_WARN_DEPRECATED \
     do { \
         static int warned = 0; \
         if (!warned) { \
             warned = 1; \
-            _objc_warn_deprecated(__FUNCTION__, NULL); \
+            _objc_inform_deprecated(__FUNCTION__, NULL); \
         } \
     } while (0) \
 
 __END_DECLS
 
+
+#ifndef STATIC_ASSERT
+#   define STATIC_ASSERT(x) _STATIC_ASSERT2(x, __LINE__)
+#   define _STATIC_ASSERT2(x, line) _STATIC_ASSERT3(x, line)
+#   define _STATIC_ASSERT3(x, line)                                     \
+        typedef struct {                                                \
+            int _static_assert[(x) ? 0 : -1];                           \
+        } _static_assert_ ## line __attribute__((unavailable)) 
+#endif
+
+#define countof(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+
+// Global operator new and delete. We must not use any app overrides.
+// This ALSO REQUIRES each of these be in libobjc's unexported symbol list.
+#if __cplusplus
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winline-new-delete"
+#include <new>
+inline void* operator new(std::size_t size) throw (std::bad_alloc) { return _malloc_internal(size); }
+inline void* operator new[](std::size_t size) throw (std::bad_alloc) { return _malloc_internal(size); }
+inline void* operator new(std::size_t size, const std::nothrow_t&) throw() { return _malloc_internal(size); }
+inline void* operator new[](std::size_t size, const std::nothrow_t&) throw() { return _malloc_internal(size); }
+inline void operator delete(void* p) throw() { _free_internal(p); }
+inline void operator delete[](void* p) throw() { _free_internal(p); }
+inline void operator delete(void* p, const std::nothrow_t&) throw() { _free_internal(p); }
+inline void operator delete[](void* p, const std::nothrow_t&) throw() { _free_internal(p); }
+#pragma clang diagnostic pop
+#endif
+
+
+// DisguisedPtr<T> acts like pointer type T*, except the 
+// stored value is disguised to hide it from tools like `leaks`.
+// nil is disguised as itself so zero-filled memory works as expected, 
+// which means 0x80..00 is also diguised as itself but we don't care
+template <typename T>
+class DisguisedPtr {
+    uintptr_t value;
+
+    static uintptr_t disguise(T* ptr) {
+        return -(uintptr_t)ptr;
+    }
+
+    static T* undisguise(uintptr_t val) {
+        return (T*)-val;
+    }
+
+ public:
+    DisguisedPtr() { }
+    DisguisedPtr(T* ptr) 
+        : value(disguise(ptr)) { }
+    DisguisedPtr(const DisguisedPtr<T>& ptr) 
+        : value(ptr.value) { }
+
+    DisguisedPtr<T>& operator = (T* rhs) {
+        value = disguise(rhs);
+        return *this;
+    }
+    DisguisedPtr<T>& operator = (const DisguisedPtr<T>& rhs) {
+        value = rhs.value;
+        return *this;
+    }
+
+    operator T* () const {
+        return undisguise(value);
+    }
+    T* operator -> () const { 
+        return undisguise(value);
+    }
+    T& operator * () const { 
+        return *undisguise(value);
+    }
+    T& operator [] (size_t i) const {
+        return undisguise(value)[i];
+    }
+
+    // pointer arithmetic operators omitted 
+    // because we don't currently use them anywhere
+};
+
+
+// Pointer hash function.
+// This is not a terrific hash, but it is fast 
+// and not outrageously flawed for our purposes.
+
+// Based on principles from http://locklessinc.com/articles/fast_hash/
+// and evaluation ideas from http://floodyberry.com/noncryptohashzoo/
+#if __LP64__
+static inline uint32_t ptr_hash(uint64_t key)
+{
+    key ^= key >> 4;
+    key *= 0x8a970be7488fda55;
+    key ^= __builtin_bswap64(key);
+    return (uint32_t)key;
+}
+#else
+static inline uint32_t ptr_hash(uint32_t key)
+{
+    key ^= key >> 4;
+    key *= 0x5052acdb;
+    key ^= __builtin_bswap32(key);
+    return key;
+}
+#endif
+
+/*
+  Higher-quality hash function. This is measurably slower in some workloads.
+#if __LP64__
+ uint32_t ptr_hash(uint64_t key)
+{
+    key -= __builtin_bswap64(key);
+    key *= 0x8a970be7488fda55;
+    key ^= __builtin_bswap64(key);
+    key *= 0x8a970be7488fda55;
+    key ^= __builtin_bswap64(key);
+    return (uint32_t)key;
+}
+#else
+static uint32_t ptr_hash(uint32_t key)
+{
+    key -= __builtin_bswap32(key);
+    key *= 0x5052acdb;
+    key ^= __builtin_bswap32(key);
+    key *= 0x5052acdb;
+    key ^= __builtin_bswap32(key);
+    return key;
+}
+#endif
+*/
+
+
+// Inlined parts of objc_object's implementation
+#include "objc-object.h"
+
 #endif /* _OBJC_PRIVATE_H_ */