Re-enable fast-ARC mode when possible.

Define _ARCCompliantRetainRelease on 32bit platforms and when
we have copmiler intrinsics for atomic operations that allow us
to extend the refcount field to match libobjc2.

The effective maximum reference count is still 2^24 - 1 in either
case.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@40183 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
thebeing 2016-10-28 08:30:16 +00:00
parent ce1453234b
commit ce18b5a8e5
2 changed files with 44 additions and 13 deletions

View file

@ -1,3 +1,11 @@
2016-10-28 Niels Grewe <niels.grewe@halbordnung.de>
* Source/NSObject.m: Re-enable fast-ARC mode when memory layout
and atomic operations support permit. This changes the size of the
field where the reference count is stored to the size of a pointer
in some configurations.
The effective maximum reference count is still 2^24 - 1.
2016-10-27 Wolfgang Lux <wolfgang.lux@gmail.com>
* Source/NSObject.m: Comment out _ARCCompliantRetainRelease for

View file

@ -187,15 +187,29 @@ static void GSLogZombie(id o, SEL sel)
#endif
/*
* Traditionally, GNUstep has been using a 32bit reference count in front
* of the object. The automatic reference counting implementation in
* libobjc2 uses an intptr_t instead, so NSObject will only be compatible
* with ARC if either of the following apply:
*
* a) sizeof(intptr_t) == sizeof(int32_t)
* b) we can provide atomic operations on pointer sized values, allowing
* us to extend the refcount to intptr_t.
*/
#ifdef GS_ARC_COMPATIBLE
#undef GS_ARC_COMPATIBLE
#endif
#if defined(__llvm__) || (defined(USE_ATOMIC_BUILTINS) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)))
/* Use the GCC atomic operations with recent GCC versions */
typedef int32_t volatile *gsatomic_t;
typedef intptr_t volatile *gsatomic_t;
typedef intptr_t gsrefcount_t;
#define GSATOMICREAD(X) (*(X))
#define GSAtomicIncrement(X) __sync_add_and_fetch(X, 1)
#define GSAtomicDecrement(X) __sync_sub_and_fetch(X, 1)
#define GS_ARC_COMPATIBLE 1
#elif defined(_WIN32)
@ -203,7 +217,7 @@ typedef int32_t volatile *gsatomic_t;
*/
typedef int32_t volatile *gsatomic_t;
typedef int32_t gsrefcount_t;
#ifndef _WIN64
#undef InterlockedIncrement
#undef InterlockedDecrement
@ -221,6 +235,7 @@ LONG WINAPI InterlockedDecrement(LONG volatile *);
*/
typedef int32_t volatile *gsatomic_t;
typedef int32_t gsrefcount_t;
#define GSATOMICREAD(X) (*(X))
@ -254,6 +269,7 @@ GSAtomicDecrement(gsatomic_t X)
#elif defined(__PPC__) || defined(__POWERPC__)
typedef int32_t volatile *gsatomic_t;
typedef int32_t gsrefcount_t;
#define GSATOMICREAD(X) (*(X))
@ -292,6 +308,7 @@ GSAtomicDecrement(gsatomic_t X)
#elif defined(__m68k__)
typedef int32_t volatile *gsatomic_t;
typedef int32_t gsrefcount_t;
#define GSATOMICREAD(X) (*(X))
@ -316,6 +333,7 @@ GSAtomicDecrement(gsatomic_t X)
#elif defined(__mips__)
typedef int32_t volatile *gsatomic_t;
typedef int32_t gsrefcount_t;
#define GSATOMICREAD(X) (*(X))
@ -382,6 +400,17 @@ static inline NSLock *GSAllocationLockForObject(id p)
#endif
#ifndef GS_ARC_COMPATIBLE
/*
* If we haven't previously declared that we can work in fast-ARC mode,
* check whether a point is 32bit (4 bytes) wide, which also enables ARC
* integration.
*/
# if __SIZEOF_POINTER__ == 4
# define GS_ARC_COMPATIBLE 1
# endif
#endif
#if defined(__GNUC__) && __GNUC__ < 4
#define __builtin_offsetof(s, f) (uintptr_t)(&(((s*)0)->f))
#endif
@ -438,7 +467,7 @@ NSDecrementExtraRefCountWasZero(id anObject)
if (allocationLock != 0)
{
#if defined(GSATOMICREAD)
int32_t result;
gsrefcount_t result;
result = GSAtomicDecrement((gsatomic_t)&(((obj)anObject)[-1].retained));
if (result < 0)
@ -597,6 +626,8 @@ callCXXConstructors(Class aClass, id anObject)
* the start of each object.
*/
// FIXME rewrite object allocation to use class_createInstance when we
// are using libobjc2.
inline id
NSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone *zone)
{
@ -735,15 +766,7 @@ NSShouldRetainWithZone (NSObject *anObject, NSZone *requestedZone)
* </p>
*/
@implementation NSObject
#if 0
/* Commented out for now, since the representation of object retain
* counts in gnustep-base and libobjc2 currently is not compatible.
* While gnustep-base uses int32_t libobjc2 uses intptr_t, which makes
* a difference on 64-bit architectures.
*/
// FIXME Rewrite retain/release to use objc_retain/objc_release and
// similarly object allocation to use class_createInstance when we
// are using libobjc2.
#if defined(GS_ARC_COMPATIBLE)
- (void)_ARCCompliantRetainRelease {}
#endif