/*
- * 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;
};
return retval;
}
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
__private_extern__ void __CFAllocatorDeallocate(CFTypeRef cf);
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;
#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);
}
static struct __CFAllocator __kCFAllocatorMalloc = {
INIT_CFRUNTIME_BASE(),
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
__CFAllocatorCustomSize,
__CFAllocatorCustomMalloc,
__CFAllocatorCustomCalloc,
NULL,
NULL,
&__CFAllocatorZoneIntrospect,
+ 6,
+ NULL,
NULL,
#endif
NULL, // _allocator
static struct __CFAllocator __kCFAllocatorMallocZone = {
INIT_CFRUNTIME_BASE(),
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
__CFAllocatorCustomSize,
__CFAllocatorCustomMalloc,
__CFAllocatorCustomCalloc,
NULL,
NULL,
&__CFAllocatorZoneIntrospect,
+ 6,
+ NULL,
NULL,
#endif
NULL, // _allocator
static struct __CFAllocator __kCFAllocatorSystemDefault = {
INIT_CFRUNTIME_BASE(),
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
__CFAllocatorCustomSize,
__CFAllocatorCustomMalloc,
__CFAllocatorCustomCalloc,
NULL,
NULL,
&__CFAllocatorZoneIntrospect,
+ 6,
+ NULL,
NULL,
#endif
NULL, // _allocator
static struct __CFAllocator __kCFAllocatorNull = {
INIT_CFRUNTIME_BASE(),
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
__CFAllocatorNullSize,
__CFAllocatorNullMalloc,
__CFAllocatorNullCalloc,
NULL,
NULL,
&__CFAllocatorNullZoneIntrospect,
+ 6,
+ NULL,
NULL,
#endif
NULL, // _allocator
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;
if (NULL != releaseFunc) {
INVOKE_CALLBACK1(releaseFunc, self->_context.info);
}
- _CFAllocatorDeallocateGC(allocator, (void *)self);
+ if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) CFAllocatorDeallocate(allocator, (void *)self);
}
}
"CFAllocator",
NULL, // init
NULL, // copy
- __CFAllocatorDeallocate,
+ NULL,
NULL, // equal
NULL, // hash
NULL, //
_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;
__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);
}
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
}
// 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);
}
}
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
}
} 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;
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;
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;
}
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);
}
__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);
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);
}
__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);
}
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);
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);
}
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);
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);
}
}
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);
}
__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;
}
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);
#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);
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)) {
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);
// -------- -------- -------- -------- -------- -------- -------- --------
-#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;
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;
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));
}
}
// 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
+}