]> git.saurik.com Git - apple/cf.git/blobdiff - CFBase.c
CF-635.15.tar.gz
[apple/cf.git] / CFBase.c
index df5f2aff487543711ec5afb59232454047ec3c6e..195d2dab25e907ac20f052fb1dd326cd95f7e6bd 100644 (file)
--- a/CFBase.c
+++ b/CFBase.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2011 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
+
 /*     CFBase.c
-       Copyright 1998-2002, Apple, Inc. All rights reserved.
+       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
 #include <CoreFoundation/CFBase.h>
 #include "CFInternal.h"
-#include <pthread.h>
-#include <malloc/malloc.h>
-extern size_t malloc_good_size(size_t size);
-#include <mach/mach.h>
-#include <dlfcn.h>
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+    #include <pthread.h>
+#endif
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+    #include <malloc/malloc.h>
+    extern size_t malloc_good_size(size_t size);
+    #include <mach/mach.h>
+    #include <dlfcn.h>
+#endif
 #include <stdlib.h>
 #include <string.h>
 
-#if defined(__CYGWIN32__) || defined (D__CYGWIN_)
-#error CoreFoundation is currently built with the Microsoft C Runtime, which is incompatible with the Cygwin DLL.  You must either use the -mno-cygwin flag, or complete a port of CF to the Cygwin environment.
-#endif
-
 // -------- -------- -------- -------- -------- -------- -------- --------
 
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
 // CFAllocator structure must match struct _malloc_zone_t!
 // The first two reserved fields in struct _malloc_zone_t are for us with CFRuntimeBase
+#endif
+
+
 struct __CFAllocator {
     CFRuntimeBase _base;
-    size_t (*size)(struct _malloc_zone_t *zone, const void *ptr); /* returns the size of a block or 0 if not in this zone; must be fast, especially for negative answers */
-    void *(*malloc)(struct _malloc_zone_t *zone, size_t size);
-    void *(*calloc)(struct _malloc_zone_t *zone, size_t num_items, size_t size); /* same as malloc, but block returned is set to zero */
-    void *(*valloc)(struct _malloc_zone_t *zone, size_t size); /* same as malloc, but block returned is set to zero and is guaranteed to be page aligned */
-    void (*free)(struct _malloc_zone_t *zone, void *ptr);
-    void *(*realloc)(struct _malloc_zone_t *zone, void *ptr, size_t size);
-    void (*destroy)(struct _malloc_zone_t *zone); /* zone is destroyed and all memory reclaimed */
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+    size_t     (*size)(struct _malloc_zone_t *zone, const void *ptr); /* returns the size of a block or 0 if not in this zone; must be fast, especially for negative answers */
+    void       *(*malloc)(struct _malloc_zone_t *zone, size_t size);
+    void       *(*calloc)(struct _malloc_zone_t *zone, size_t num_items, size_t size); /* same as malloc, but block returned is set to zero */
+    void       *(*valloc)(struct _malloc_zone_t *zone, size_t size); /* same as malloc, but block returned is set to zero and is guaranteed to be page aligned */
+    void       (*free)(struct _malloc_zone_t *zone, void *ptr);
+    void       *(*realloc)(struct _malloc_zone_t *zone, void *ptr, size_t size);
+    void       (*destroy)(struct _malloc_zone_t *zone); /* zone is destroyed and all memory reclaimed */
     const char *zone_name;
-    unsigned (*batch_malloc)(struct _malloc_zone_t *zone, size_t size, void **results, unsigned num_requested); /* given a size, returns pointers capable of holding that size; returns the number of pointers allocated (maybe 0 or less than num_requested) */
-    void (*batch_free)(struct _malloc_zone_t *zone, void **to_be_freed, unsigned num_to_be_freed); /* frees all the pointers in to_be_freed; note that to_be_freed may be overwritten during the process */
+
+    /* Optional batch callbacks; these may be NULL */
+    unsigned   (*batch_malloc)(struct _malloc_zone_t *zone, size_t size, void **results, unsigned num_requested); /* given a size, returns pointers capable of holding that size; returns the number of pointers allocated (maybe 0 or less than num_requested) */
+    void       (*batch_free)(struct _malloc_zone_t *zone, void **to_be_freed, unsigned num_to_be_freed); /* frees all the pointers in to_be_freed; note that to_be_freed may be overwritten during the process */
+
     struct malloc_introspection_t      *introspect;
-    void       *reserved5;
+    unsigned   version;
+    
+    /* aligned memory allocation. The callback may be NULL. */
+       void *(*memalign)(struct _malloc_zone_t *zone, size_t alignment, size_t size);
+    
+    /* free a pointer known to be in zone and known to have the given size. The callback may be NULL. */
+    void (*free_definite_size)(struct _malloc_zone_t *zone, void *ptr, size_t size);
+#endif
     CFAllocatorRef _allocator;
     CFAllocatorContext _context;
 };
@@ -103,7 +119,7 @@ CF_INLINE CFAllocatorPreferredSizeCallBack __CFAllocatorGetPreferredSizeFunction
     return retval;
 }
 
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
 
 __private_extern__ void __CFAllocatorDeallocate(CFTypeRef cf);
 
@@ -140,6 +156,7 @@ static void *__CFAllocatorCustomCalloc(malloc_zone_t *zone, size_t num_items, si
 
 static void *__CFAllocatorCustomValloc(malloc_zone_t *zone, size_t size) {
     CFAllocatorRef allocator = (CFAllocatorRef)zone;
+    if (size >= ULONG_MAX - 2 * vm_page_size) return NULL; // avoid integer overflow plus don't allow all pages to be allocated either
     void *newptr = CFAllocatorAllocate(allocator, size + vm_page_size, 0);
     newptr = (void *)round_page((uintptr_t)newptr);
     return newptr;
@@ -241,7 +258,7 @@ static void __CFAllocatorSystemDeallocate(void *ptr, void *info) {
 
 #endif
 
-#if defined(__WIN32__) || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+#if DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
 static void *__CFAllocatorSystemAllocate(CFIndex size, CFOptionFlags hint, void *info) {
     return malloc(size);
 }
@@ -281,7 +298,7 @@ static void __CFAllocatorCPPFree(void *ptr, void *info)
 
 static struct __CFAllocator __kCFAllocatorMalloc = {
     INIT_CFRUNTIME_BASE(),
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     __CFAllocatorCustomSize,
     __CFAllocatorCustomMalloc,
     __CFAllocatorCustomCalloc,
@@ -293,6 +310,8 @@ static struct __CFAllocator __kCFAllocatorMalloc = {
     NULL,
     NULL,
     &__CFAllocatorZoneIntrospect,
+    6,
+    NULL,
     NULL,
 #endif
     NULL,      // _allocator
@@ -308,7 +327,7 @@ static struct __CFAllocator __kCFAllocatorMalloc = {
 
 static struct __CFAllocator __kCFAllocatorMallocZone = {
     INIT_CFRUNTIME_BASE(),
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     __CFAllocatorCustomSize,
     __CFAllocatorCustomMalloc,
     __CFAllocatorCustomCalloc,
@@ -320,6 +339,8 @@ static struct __CFAllocator __kCFAllocatorMallocZone = {
     NULL,
     NULL,
     &__CFAllocatorZoneIntrospect,
+    6,
+    NULL,
     NULL,
 #endif
     NULL,      // _allocator
@@ -328,7 +349,7 @@ static struct __CFAllocator __kCFAllocatorMallocZone = {
 
 static struct __CFAllocator __kCFAllocatorSystemDefault = {
     INIT_CFRUNTIME_BASE(),
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     __CFAllocatorCustomSize,
     __CFAllocatorCustomMalloc,
     __CFAllocatorCustomCalloc,
@@ -340,6 +361,8 @@ static struct __CFAllocator __kCFAllocatorSystemDefault = {
     NULL,
     NULL,
     &__CFAllocatorZoneIntrospect,
+    6,
+    NULL,
     NULL,
 #endif
     NULL,      // _allocator
@@ -348,7 +371,7 @@ static struct __CFAllocator __kCFAllocatorSystemDefault = {
 
 static struct __CFAllocator __kCFAllocatorNull = {
     INIT_CFRUNTIME_BASE(),
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     __CFAllocatorNullSize,
     __CFAllocatorNullMalloc,
     __CFAllocatorNullCalloc,
@@ -360,6 +383,8 @@ static struct __CFAllocator __kCFAllocatorNull = {
     NULL,
     NULL,
     &__CFAllocatorNullZoneIntrospect,
+    6,
+    NULL,
     NULL,
 #endif
     NULL,      // _allocator
@@ -371,7 +396,11 @@ const CFAllocatorRef kCFAllocatorSystemDefault = &__kCFAllocatorSystemDefault;
 const CFAllocatorRef kCFAllocatorMalloc = &__kCFAllocatorMalloc;
 const CFAllocatorRef kCFAllocatorMallocZone = &__kCFAllocatorMallocZone;
 const CFAllocatorRef kCFAllocatorNull = &__kCFAllocatorNull;
-const CFAllocatorRef kCFAllocatorUseContext = (CFAllocatorRef)0x0257;
+const CFAllocatorRef kCFAllocatorUseContext = (CFAllocatorRef)0x03ab;
+#undef kCFAllocatorSystemDefaultGCRefZero
+#undef kCFAllocatorDefaultGCRefZero
+const CFAllocatorRef kCFAllocatorSystemDefaultGCRefZero = (CFAllocatorRef)0x03ad;
+const CFAllocatorRef kCFAllocatorDefaultGCRefZero = (CFAllocatorRef)0x03af;
 
 static CFStringRef __CFAllocatorCopyDescription(CFTypeRef cf) {
     CFAllocatorRef self = (CFAllocatorRef)cf;
@@ -405,7 +434,7 @@ __private_extern__ void __CFAllocatorDeallocate(CFTypeRef cf) {
        if (NULL != releaseFunc) {
            INVOKE_CALLBACK1(releaseFunc, self->_context.info);
        }
-       _CFAllocatorDeallocateGC(allocator, (void *)self);
+        if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) CFAllocatorDeallocate(allocator, (void *)self);
     }
 }
 
@@ -416,7 +445,7 @@ static const CFRuntimeClass __CFAllocatorClass = {
     "CFAllocator",
     NULL,      // init
     NULL,      // copy
-    __CFAllocatorDeallocate,
+    NULL,
     NULL,      // equal
     NULL,      // hash
     NULL,      // 
@@ -428,9 +457,8 @@ __private_extern__ void __CFAllocatorInitialize(void) {
 
     _CFRuntimeSetInstanceTypeID(&__kCFAllocatorSystemDefault, __kCFAllocatorTypeID);
     __kCFAllocatorSystemDefault._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
-#if DEPLOYMENT_TARGET_MACOSX
-    __kCFAllocatorSystemDefault._context.info = (CF_USING_COLLECTABLE_MEMORY ? __CFCollectableZone : malloc_default_zone());
-    memset(malloc_default_zone(), 0, 2 * sizeof(void *));
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+    __kCFAllocatorSystemDefault._context.info = (kCFUseCollectableAllocator ? objc_collectableZone() : malloc_default_zone());
 #endif
     __kCFAllocatorSystemDefault._allocator = kCFAllocatorSystemDefault;
 
@@ -438,12 +466,12 @@ __private_extern__ void __CFAllocatorInitialize(void) {
     __kCFAllocatorMalloc._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
     __kCFAllocatorMalloc._allocator = kCFAllocatorSystemDefault;
 
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
        _CFRuntimeSetInstanceTypeID(&__kCFAllocatorMallocZone, __kCFAllocatorTypeID);
     __kCFAllocatorMallocZone._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
     __kCFAllocatorMallocZone._allocator = kCFAllocatorSystemDefault;
     __kCFAllocatorMallocZone._context.info = malloc_default_zone();
-#endif //__MACH__
+#endif
 
     _CFRuntimeSetInstanceTypeID(&__kCFAllocatorNull, __kCFAllocatorTypeID);
     __kCFAllocatorNull._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
@@ -456,21 +484,20 @@ CFTypeID CFAllocatorGetTypeID(void) {
 }
 
 CFAllocatorRef CFAllocatorGetDefault(void) {
-    CFAllocatorRef allocator = (CFAllocatorRef)__CFGetThreadSpecificData_inline()->_allocator;
-    if (NULL == allocator) {
-       allocator = kCFAllocatorSystemDefault;
-    }
-    return allocator;
+    return __CFGetDefaultAllocator();
 }
 
 void CFAllocatorSetDefault(CFAllocatorRef allocator) {
-    CFAllocatorRef current = (CFAllocatorRef)__CFGetThreadSpecificData_inline()->_allocator;
+    if (kCFAllocatorSystemDefaultGCRefZero == allocator || kCFAllocatorDefaultGCRefZero == allocator) {
+        HALT;
+    }
+    CFAllocatorRef current = __CFGetDefaultAllocator();
 #if defined(DEBUG) 
     if (NULL != allocator) {
        __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
     }
 #endif
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     if (allocator && allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {      // malloc_zone_t *
        return;         // require allocator to this function to be an allocator
     }
@@ -481,7 +508,7 @@ void CFAllocatorSetDefault(CFAllocatorRef allocator) {
        // We retain an extra time so that anything set as the default
        // allocator never goes away.
        CFRetain(allocator);
-       __CFGetThreadSpecificData_inline()->_allocator = (void *)allocator;
+        _CFSetTSD(__CFTSDKeyAllocator, (void *)allocator, NULL);
     }
 }
 
@@ -490,7 +517,7 @@ static CFAllocatorRef __CFAllocatorCreate(CFAllocatorRef allocator, CFAllocatorC
     CFAllocatorRetainCallBack retainFunc;
     CFAllocatorAllocateCallBack allocateFunc;
     void *retainedInfo;
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     if (allocator && kCFAllocatorUseContext != allocator && allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {       // malloc_zone_t *
        return NULL;    // require allocator to this function to be an allocator
     }
@@ -516,11 +543,12 @@ static CFAllocatorRef __CFAllocatorCreate(CFAllocatorRef allocator, CFAllocatorC
     } else {
        allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
        memory = (struct __CFAllocator *)CFAllocatorAllocate(allocator, sizeof(struct __CFAllocator), __kCFAllocatorGCObjectMemory);
-       if (__CFOASafe) __CFSetLastAllocationEventName(memory, "CFAllocator");
        if (NULL == memory) {
            return NULL;
        }
+       if (__CFOASafe) __CFSetLastAllocationEventName(memory, "CFAllocator");
     }
+    memset(memory, 0, sizeof(CFRuntimeBase));
     memory->_base._cfisa = 0;
 #if __LP64__
     memory->_base._rc = 1;
@@ -530,7 +558,7 @@ static CFAllocatorRef __CFAllocatorCreate(CFAllocatorRef allocator, CFAllocatorC
     memory->_base._cfinfo[CF_INFO_BITS] = 0;
     _CFRuntimeSetInstanceTypeID(memory, __kCFAllocatorTypeID);
     memory->_base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     memory->size = __CFAllocatorCustomSize;
     memory->malloc = __CFAllocatorCustomMalloc;
     memory->calloc = __CFAllocatorCustomCalloc;
@@ -542,7 +570,9 @@ static CFAllocatorRef __CFAllocatorCreate(CFAllocatorRef allocator, CFAllocatorC
     memory->batch_malloc = NULL;
     memory->batch_free = NULL;
     memory->introspect = &__CFAllocatorZoneIntrospect;
-    memory->reserved5 = NULL;
+    memory->version = 6;
+    memory->memalign = NULL;
+    memory->free_definite_size = NULL;
 #endif
     memory->_allocator = allocator;
     memory->_context.version = context->version;
@@ -564,23 +594,26 @@ static CFAllocatorRef __CFAllocatorCreate(CFAllocatorRef allocator, CFAllocatorC
 }
 
 CFAllocatorRef CFAllocatorCreate(CFAllocatorRef allocator, CFAllocatorContext *context) {
-    CFAssert1(!CF_USING_COLLECTABLE_MEMORY, __kCFLogAssertion, "%s(): Shouldn't be called when GC is enabled!", __PRETTY_FUNCTION__);
-#if defined(DEBUG)
-    if (CF_USING_COLLECTABLE_MEMORY)
-        HALT;
-#endif
-    return __CFAllocatorCreate(allocator, context);
-}
-
-CFAllocatorRef _CFAllocatorCreateGC(CFAllocatorRef allocator, CFAllocatorContext *context) {
     return __CFAllocatorCreate(allocator, context);
 }
 
 void *CFAllocatorAllocate(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint) {
     CFAllocatorAllocateCallBack allocateFunc;
     void *newptr = NULL;
-    allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
-#if (DEPLOYMENT_TARGET_MACOSX) && defined(DEBUG)
+
+    Boolean initialRefcountOne = true;
+    if (kCFAllocatorSystemDefaultGCRefZero == allocator) {
+       allocator = kCFAllocatorSystemDefault;
+       initialRefcountOne = false;
+    } else if (kCFAllocatorDefaultGCRefZero == allocator) {
+        // Under GC, we can't use just any old allocator when the GCRefZero allocator was requested
+       allocator = kCFUseCollectableAllocator ? kCFAllocatorSystemDefault : __CFGetDefaultAllocator();
+       if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) initialRefcountOne = false;
+    } else if (NULL == allocator) {
+       allocator = __CFGetDefaultAllocator();
+    }
+
+#if defined(DEBUG) && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED)
     if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
        __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
     }
@@ -588,13 +621,13 @@ void *CFAllocatorAllocate(CFAllocatorRef allocator, CFIndex size, CFOptionFlags
     __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
 #endif
     if (0 == size) return NULL;
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {   // malloc_zone_t *
        return malloc_zone_malloc((malloc_zone_t *)allocator, size);
     }
 #endif
     if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
-       newptr = auto_zone_allocate_object((auto_zone_t*)allocator->_context.info, size, CF_GET_GC_MEMORY_TYPE(hint), true, false);
+       newptr = auto_zone_allocate_object((auto_zone_t*)allocator->_context.info, size, CF_GET_GC_MEMORY_TYPE(hint), initialRefcountOne, false);
     } else {
        newptr = NULL;
        allocateFunc = __CFAllocatorGetAllocateFunction(&allocator->_context);
@@ -610,8 +643,17 @@ void *CFAllocatorReallocate(CFAllocatorRef allocator, void *ptr, CFIndex newsize
     CFAllocatorReallocateCallBack reallocateFunc;
     CFAllocatorDeallocateCallBack deallocateFunc;
     void *newptr;
-    allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
-#if (DEPLOYMENT_TARGET_MACOSX) && defined(DEBUG)
+
+    if (kCFAllocatorSystemDefaultGCRefZero == allocator) {
+        allocator = kCFAllocatorSystemDefault;
+    } else if (kCFAllocatorDefaultGCRefZero == allocator) {
+        // Under GC, we can't use just any old allocator when the GCRefZero allocator was requested
+       allocator = kCFUseCollectableAllocator ? kCFAllocatorSystemDefault : __CFGetDefaultAllocator();
+    } else if (NULL == allocator) {
+        allocator = __CFGetDefaultAllocator();
+    }
+
+#if defined(DEBUG) && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED)
     if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
        __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
     }
@@ -619,7 +661,7 @@ void *CFAllocatorReallocate(CFAllocatorRef allocator, void *ptr, CFIndex newsize
     __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
 #endif
     if (NULL == ptr && 0 < newsize) {
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
        if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {        // malloc_zone_t *
            return malloc_zone_malloc((malloc_zone_t *)allocator, newsize);
        }
@@ -632,7 +674,7 @@ void *CFAllocatorReallocate(CFAllocatorRef allocator, void *ptr, CFIndex newsize
        return newptr;
     }
     if (NULL != ptr && 0 == newsize) {
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
        if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {        // malloc_zone_t *
 #if defined(DEBUG)
            size_t size = malloc_size(ptr);
@@ -649,7 +691,7 @@ void *CFAllocatorReallocate(CFAllocatorRef allocator, void *ptr, CFIndex newsize
        return NULL;
     }
     if (NULL == ptr && 0 == newsize) return NULL;
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {   // malloc_zone_t *
        return malloc_zone_realloc((malloc_zone_t *)allocator, ptr, newsize);
     }
@@ -662,15 +704,26 @@ void *CFAllocatorReallocate(CFAllocatorRef allocator, void *ptr, CFIndex newsize
 
 void CFAllocatorDeallocate(CFAllocatorRef allocator, void *ptr) {
     CFAllocatorDeallocateCallBack deallocateFunc;
-    allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
-#if (DEPLOYMENT_TARGET_MACOSX) && defined(DEBUG)
+
+    if (kCFAllocatorSystemDefaultGCRefZero == allocator) {
+        if (_CFAllocatorIsGCRefZero(allocator)) return;
+        allocator = kCFAllocatorSystemDefault;
+    } else if (kCFAllocatorDefaultGCRefZero == allocator) {
+        // Under GC, we can't use just any old allocator when the GCRefZero allocator was requested
+       allocator = kCFUseCollectableAllocator ? kCFAllocatorSystemDefault : __CFGetDefaultAllocator();
+       if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) return;
+    } else if (NULL == allocator) {
+        allocator = __CFGetDefaultAllocator();
+    }
+
+#if defined(DEBUG) && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED)
     if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
        __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
     }
 #else
     __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
 #endif
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {   // malloc_zone_t *
 #if defined(DEBUG)
        size_t size = malloc_size(ptr);
@@ -688,15 +741,24 @@ void CFAllocatorDeallocate(CFAllocatorRef allocator, void *ptr) {
 CFIndex CFAllocatorGetPreferredSizeForSize(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint) {
     CFAllocatorPreferredSizeCallBack prefFunc;
     CFIndex newsize = 0;
-    allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
-#if (DEPLOYMENT_TARGET_MACOSX) && defined(DEBUG)
+
+    if (kCFAllocatorSystemDefaultGCRefZero == allocator) {
+        allocator = kCFAllocatorSystemDefault;
+    } else if (kCFAllocatorDefaultGCRefZero == allocator) {
+        // Under GC, we can't use just any old allocator when the GCRefZero allocator was requested
+       allocator = kCFUseCollectableAllocator ? kCFAllocatorSystemDefault : __CFGetDefaultAllocator();
+    } else if (NULL == allocator) {
+        allocator = __CFGetDefaultAllocator();
+    }
+
+#if defined(DEBUG) && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED)
     if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
        __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
     }
 #else
     __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
 #endif
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {   // malloc_zone_t *
        return malloc_good_size(size);
     }
@@ -710,8 +772,16 @@ CFIndex CFAllocatorGetPreferredSizeForSize(CFAllocatorRef allocator, CFIndex siz
 }
 
 void CFAllocatorGetContext(CFAllocatorRef allocator, CFAllocatorContext *context) {
-    allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
-#if (DEPLOYMENT_TARGET_MACOSX) && defined(DEBUG)
+    if (kCFAllocatorSystemDefaultGCRefZero == allocator) {
+        allocator = kCFAllocatorSystemDefault;
+    } else if (kCFAllocatorDefaultGCRefZero == allocator) {
+        // Under GC, we can't use just any old allocator when the GCRefZero allocator was requested
+       allocator = kCFUseCollectableAllocator ? kCFAllocatorSystemDefault : __CFGetDefaultAllocator();
+    } else if (NULL == allocator) {
+        allocator = __CFGetDefaultAllocator();
+    }
+
+#if defined(DEBUG) && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED)
     if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
        __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
     }
@@ -719,7 +789,7 @@ void CFAllocatorGetContext(CFAllocatorRef allocator, CFAllocatorContext *context
     __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
 #endif
     CFAssert1(0 == context->version, __kCFLogAssertion, "%s(): context version not initialized to 0", __PRETTY_FUNCTION__);
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {   // malloc_zone_t *
        return;
     }
@@ -733,7 +803,7 @@ void CFAllocatorGetContext(CFAllocatorRef allocator, CFAllocatorContext *context
     context->reallocate = __CFAllocatorGetReallocateFunction(&allocator->_context);
     context->deallocate = __CFAllocatorGetDeallocateFunction(&allocator->_context);
     context->preferredSize = __CFAllocatorGetPreferredSizeFunction(&allocator->_context);
-#if (DEPLOYMENT_TARGET_MACOSX) && defined(__ppc__)
+#if SUPPORT_CFM
     context->retain = (void *)((uintptr_t)context->retain & ~0x3);
     context->release = (void *)((uintptr_t)context->release & ~0x3);
     context->copyDescription = (void *)((uintptr_t)context->copyDescription & ~0x3);
@@ -744,7 +814,7 @@ void CFAllocatorGetContext(CFAllocatorRef allocator, CFAllocatorContext *context
 #endif
 }
 
-void *_CFAllocatorAllocateGC(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint)
+__private_extern__ void *_CFAllocatorAllocateGC(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint)
 {
     if (CF_IS_COLLECTABLE_ALLOCATOR(allocator))
         return auto_zone_allocate_object((auto_zone_t*)kCFAllocatorSystemDefault->_context.info, size, CF_GET_GC_MEMORY_TYPE(hint), false, false);
@@ -752,7 +822,7 @@ void *_CFAllocatorAllocateGC(CFAllocatorRef allocator, CFIndex size, CFOptionFla
         return CFAllocatorAllocate(allocator, size, hint);
 }
 
-void *_CFAllocatorReallocateGC(CFAllocatorRef allocator, void *ptr, CFIndex newsize, CFOptionFlags hint)
+__private_extern__ void *_CFAllocatorReallocateGC(CFAllocatorRef allocator, void *ptr, CFIndex newsize, CFOptionFlags hint)
 {
     if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
        if (ptr && (newsize == 0)) {
@@ -766,7 +836,7 @@ void *_CFAllocatorReallocateGC(CFAllocatorRef allocator, void *ptr, CFIndex news
     return CFAllocatorReallocate(allocator, ptr, newsize, hint);
 }
 
-void _CFAllocatorDeallocateGC(CFAllocatorRef allocator, void *ptr)
+__private_extern__ void _CFAllocatorDeallocateGC(CFAllocatorRef allocator, void *ptr)
 {
     // when running GC, don't deallocate.
     if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) CFAllocatorDeallocate(allocator, ptr);
@@ -774,89 +844,6 @@ void _CFAllocatorDeallocateGC(CFAllocatorRef allocator, void *ptr)
 
 // -------- -------- -------- -------- -------- -------- -------- --------
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
-__private_extern__ pthread_key_t __CFTSDKey = (pthread_key_t)NULL;
-#endif
-#if 0
-__private_extern__ DWORD __CFTSDKey = 0xFFFFFFFF;
-#endif
-
-extern void _CFRunLoop1(void);
-
-// Called for each thread as it exits
-__private_extern__ void __CFFinalizeThreadData(void *arg) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
-    __CFThreadSpecificData *tsd = (__CFThreadSpecificData *)arg;
-#elif defined(__WIN32__)
-    __CFThreadSpecificData *tsd = (__CFThreadSpecificData*)TlsGetValue(__CFTSDKey);
-    TlsSetValue(__CFTSDKey, NULL);
-#endif
-    if (NULL == tsd) return; 
-    if (tsd->_allocator) CFRelease(tsd->_allocator);
-#if DEPLOYMENT_TARGET_MACOSX
-    _CFRunLoop1();
-#endif
-#if 0 || 0
-
-    if (tsd->_messageHook) UnhookWindowsHookEx(tsd->_messageHook);
-
-#endif
-
-    CFAllocatorDeallocate(kCFAllocatorSystemDefault, tsd);
-}
-
-__private_extern__ __CFThreadSpecificData *__CFGetThreadSpecificData(void) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
-    __CFThreadSpecificData *data;
-    data = pthread_getspecific(__CFTSDKey);
-    if (data) {
-       return data;
-    }
-    data = CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(__CFThreadSpecificData), 0);
-    if (__CFOASafe) __CFSetLastAllocationEventName(data, "CFUtilities (thread-data)");
-    memset(data, 0, sizeof(__CFThreadSpecificData));
-    pthread_setspecific(__CFTSDKey, data);
-    return data;
-#elif defined(__WIN32__)
-    __CFThreadSpecificData *data;
-    data = (__CFThreadSpecificData *)TlsGetValue(__CFTSDKey);
-    if (data) {
-       return data;
-    }
-    data = (__CFThreadSpecificData *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(__CFThreadSpecificData), 0);
-    if (__CFOASafe) __CFSetLastAllocationEventName(data, "CFUtilities (thread-data)");
-    memset(data, 0, sizeof(__CFThreadSpecificData));
-    TlsSetValue(__CFTSDKey, data);
-    return data;
-#endif
-}
-
-__private_extern__ void __CFBaseInitialize(void) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
-    pthread_key_create(&__CFTSDKey, __CFFinalizeThreadData);
-#endif
-#if 0 || 0
-    __CFTSDKey = TlsAlloc();
-#endif
-}
-
-#if 0 || 0
-__private_extern__ void __CFBaseCleanup(void) {
-    TlsFree(__CFTSDKey);
-}
-#endif
-
-
-static CFBadErrorCallBack __CFOutOfMemoryCallBack = NULL;
-
-CFBadErrorCallBack _CFGetOutOfMemoryErrorCallBack(void) {
-    return __CFOutOfMemoryCallBack;
-}
-
-void _CFSetOutOfMemoryErrorCallBack(CFBadErrorCallBack callBack) {
-    __CFOutOfMemoryCallBack = callBack;
-}
-
 
 CFRange __CFRangeMake(CFIndex loc, CFIndex len) {
     CFRange range;
@@ -914,14 +901,19 @@ CFTypeID CFNullGetTypeID(void) {
 void CFCollection_non_gc_storage_error(void) { }
 
 
+#if !SUPPORT_CFM
+void _CFRuntimeSetCFMPresent(void *addr) {
+}
+#endif
+
+#if SUPPORT_CFM
+
 static int hasCFM = 0;
 
 void _CFRuntimeSetCFMPresent(void *addr) {
     hasCFM = 1;
 }
 
-#if (DEPLOYMENT_TARGET_MACOSX) && defined(__ppc__)
-
 /* See comments below */
 __private_extern__ void __CF_FAULT_CALLBACK(void **ptr) {
     uintptr_t p = (uintptr_t)*ptr;
@@ -929,19 +921,9 @@ __private_extern__ void __CF_FAULT_CALLBACK(void **ptr) {
     if (0 == hasCFM || (0x90000000 <= p && p < 0xA0000000)) {
        *ptr = (void *)(p | 0x1);
     } else {
-       static CFMutableDictionaryRef cache = NULL;
-       static CFSpinLock_t lock = CFSpinLockInit;
        uintptr_t known = ~0;
-       __CFSpinLock(&lock);
-       if (!cache || !CFDictionaryGetValueIfPresent(cache, (const void *)p, (const void **)&known)) {
-           if (!cache) {
-               cache = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, NULL);
-           }
            Dl_info info;
            known = dladdr((void *)p, &info);
-           CFDictionarySetValue(cache, (const void *)p, (const void *)known);
-       }
-       __CFSpinUnlock(&lock);
        *ptr = (void *)(p | (known ? 0x1 : 0x3));
     }
 }
@@ -987,38 +969,19 @@ __asm__ (
 
 // void __HALT(void);
 
-#if defined(__ppc__) || defined(__ppc64__)
-__asm__ (
-".text\n"
-"      .align 2\n"
-#if DEPLOYMENT_TARGET_MACOSX
-".private_extern ___HALT\n"
-#else
-".globl ___HALT\n"
-#endif
-"___HALT:\n"
-"      trap\n"
-);
-#endif
+/* Keep this assembly at the bottom of the source file! */
+
 
-#if defined(__i386__) || defined(__x86_64__)
+extern void __HALT() {
+#if defined(__ppc__)
+    __asm__("trap");
+#elif defined(__i386__) || defined(__x86_64__)
 #if defined(_MSC_VER)
-void __HALT() {
     __asm int 3;
-}
 #else
-__asm__ (
-".text\n"
-"      .align 2, 0x90\n"
-#if DEPLOYMENT_TARGET_MACOSX
-".private_extern ___HALT\n"
-#else
-".globl ___HALT\n"
-#endif
-"___HALT:\n"
-"      int3\n"
-);
+    __asm__("int3");
 #endif
 #endif
+}