Skip to content

Commit

Permalink
Preliminary code for emulation of the objc2 runtime weak reference fe…
Browse files Browse the repository at this point in the history
…ature
  • Loading branch information
rfm committed Dec 23, 2024
1 parent e7716e6 commit 927e97e
Show file tree
Hide file tree
Showing 11 changed files with 472 additions and 81 deletions.
53 changes: 26 additions & 27 deletions Headers/GNUstepBase/GSIMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ extern "C" {
* GSI_MAP_ZEROED()
* Define this macro to check whether a map uses keys which may
* be zeroed weak pointers.
*
* GSI_MAP_NODE_CLASS
* If defined, each node in the map has an 'isa' field at the
* start which is initialised to be the specified class so that
* the node looks like an instance of that class.
*/

#ifndef GSI_MAP_HAS_VALUE
Expand Down Expand Up @@ -384,6 +389,9 @@ typedef GSIMapNode_t *GSIMapNode;
#endif

struct _GSIMapNode {
#if defined(GSI_MAP_NODE_CLASS)
void *isa; /* Node pretends to be instance of class */
#endif
GSIMapNode nextInBucket; /* Linked list of bucket. */
GSIMapKey key;
#if GSI_MAP_HAS_VALUE
Expand Down Expand Up @@ -1078,9 +1086,8 @@ GSIMapCountByEnumeratingWithStateObjectsCount(GSIMapTable map,
return count;
}

#if GSI_MAP_HAS_VALUE
GS_STATIC_INLINE GSIMapNode
GSIMapAddPairNoRetain(GSIMapTable map, GSIMapKey key, GSIMapVal value)
GSIMapGetNode(GSIMapTable map)
{
GSIMapNode node = map->freeNodes;

Expand All @@ -1090,11 +1097,24 @@ GSIMapAddPairNoRetain(GSIMapTable map, GSIMapKey key, GSIMapVal value)
node = map->freeNodes;
}
map->freeNodes = node->nextInBucket;
#if defined(GSI_MAP_NODE_CLASS)
node->isa = (void*)(GSI_MAP_NODE_CLASS);
#endif
node->nextInBucket = 0;
return node;
}


#if GSI_MAP_HAS_VALUE
GS_STATIC_INLINE GSIMapNode
GSIMapAddPairNoRetain(GSIMapTable map, GSIMapKey key, GSIMapVal value)
{
GSIMapNode node = GSIMapGetNode(map);

node->key = key;
node->value = value;
GSI_MAP_STORE_KEY(map, &node->key, key);
GSI_MAP_STORE_VALUE(map, &node->value, value);
node->nextInBucket = 0;
GSIMapRightSizeMap(map, map->nodeCount);
GSIMapAddNodeToMap(map, node);
return node;
Expand All @@ -1103,19 +1123,12 @@ GSIMapAddPairNoRetain(GSIMapTable map, GSIMapKey key, GSIMapVal value)
GS_STATIC_INLINE GSIMapNode
GSIMapAddPair(GSIMapTable map, GSIMapKey key, GSIMapVal value)
{
GSIMapNode node = map->freeNodes;
GSIMapNode node = GSIMapGetNode(map);

if (node == 0)
{
GSIMapMoreNodes(map, map->nodeCount < map->increment ? 0: map->increment);
node = map->freeNodes;
}
map->freeNodes = node->nextInBucket;
GSI_MAP_STORE_KEY(map, &node->key, key);
GSI_MAP_RETAIN_KEY(map, node->key);
GSI_MAP_STORE_VALUE(map, &node->value, value);
GSI_MAP_RETAIN_VALUE(map, node->value);
node->nextInBucket = 0;
GSIMapRightSizeMap(map, map->nodeCount);
GSIMapAddNodeToMap(map, node);
return node;
Expand All @@ -1124,16 +1137,9 @@ GSIMapAddPair(GSIMapTable map, GSIMapKey key, GSIMapVal value)
GS_STATIC_INLINE GSIMapNode
GSIMapAddKeyNoRetain(GSIMapTable map, GSIMapKey key)
{
GSIMapNode node = map->freeNodes;
GSIMapNode node = GSIMapGetNode(map);

if (node == 0)
{
GSIMapMoreNodes(map, map->nodeCount < map->increment ? 0: map->increment);
node = map->freeNodes;
}
map->freeNodes = node->nextInBucket;
GSI_MAP_STORE_KEY(map, &node->key, key);
node->nextInBucket = 0;
GSIMapRightSizeMap(map, map->nodeCount);
GSIMapAddNodeToMap(map, node);
return node;
Expand All @@ -1142,17 +1148,10 @@ GSIMapAddKeyNoRetain(GSIMapTable map, GSIMapKey key)
GS_STATIC_INLINE GSIMapNode
GSIMapAddKey(GSIMapTable map, GSIMapKey key)
{
GSIMapNode node = map->freeNodes;
GSIMapNode node = GSIMapGetNode(map);

if (node == 0)
{
GSIMapMoreNodes(map, map->nodeCount < map->increment ? 0: map->increment);
node = map->freeNodes;
}
map->freeNodes = node->nextInBucket;
GSI_MAP_STORE_KEY(map, &node->key, key);
GSI_MAP_RETAIN_KEY(map, node->key);
node->nextInBucket = 0;
GSIMapRightSizeMap(map, map->nodeCount);
GSIMapAddNodeToMap(map, node);
return node;
Expand Down
8 changes: 8 additions & 0 deletions Source/GSPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -637,5 +637,13 @@ void
GSPrivateEncodeBase64(const uint8_t *src, NSUInteger length, uint8_t *dst)
GS_ATTRIB_PRIVATE;

#ifndef OBJC_CAP_ARC
/* When we don't have a runtime with ARC to support weak references, we
* use our own version.
*/
void GSWeakInit() GS_ATTRIB_PRIVATE;
BOOL objc_delete_weak_refs(id obj);
#endif

#endif /* _GSPrivate_h_ */

4 changes: 2 additions & 2 deletions Source/NSConcreteHashTable.m
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ @interface NSConcreteHashTable : NSHashTable
pointerFunctionsReplace(&M->cb.pf, (void**)addr, (x).obj);

#define GSI_MAP_READ_KEY(M,addr) \
(M->legacy ? *(addr) :\
(__typeof__(*addr))pointerFunctionsRead(&M->cb.pf, (void**)addr))
(M->legacy ? *(addr) :\
(__typeof__(*addr))pointerFunctionsRead(&M->cb.pf, (void**)addr))

#define GSI_MAP_ENUMERATOR NSHashEnumerator

Expand Down
16 changes: 9 additions & 7 deletions Source/NSConcretePointerFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,16 @@
#endif

#if defined(OBJC_CAP_ARC)
# include <objc/objc-arc.h>
# define WEAK_READ(x) objc_loadWeak((id*)x)
# define WEAK_WRITE(addr, x) objc_storeWeak((id*)addr, (id)x)
# define STRONG_WRITE(addr, x) objc_storeStrong((id*)addr, (id)x)
# define STRONG_ACQUIRE(x) objc_retain(x)
# include <objc/objc-arc.h>
# define WEAK_READ(x) objc_loadWeak((id*)x)
# define WEAK_WRITE(addr, x) objc_storeWeak((id*)addr, (id)x)
# define STRONG_WRITE(addr, x) objc_storeStrong((id*)addr, (id)x)
# define STRONG_ACQUIRE(x) objc_retain(x)
#else
# define WEAK_READ(x) (*x)
# define WEAK_WRITE(addr, x) (*(addr) = x)
extern id objc_loadWeak(id *object);
extern id objc_storeWeak(id *addr, id obj);
# define WEAK_READ(x) objc_loadWeak((id*)x)
# define WEAK_WRITE(addr, x) objc_storeWeak((id*)addr, (id)x)
# define STRONG_WRITE(addr, x) ASSIGN(*((id*)addr), ((id)x))
# define STRONG_ACQUIRE(x) RETAIN(((id)x))
#endif
Expand Down
6 changes: 2 additions & 4 deletions Source/NSObject.m
Original file line number Diff line number Diff line change
Expand Up @@ -493,9 +493,7 @@ static BOOL objc_release_fast_no_destroy_internal(id anObject)
* have been greater than zero)
*/
(((obj)anObject)[-1].retained) = 0;
# ifdef OBJC_CAP_ARC
objc_delete_weak_refs(anObject);
# endif
return YES;
}
#else /* GSATOMICREAD */
Expand All @@ -504,9 +502,7 @@ static BOOL objc_release_fast_no_destroy_internal(id anObject)
pthread_mutex_lock(theLock);
if (((obj)anObject)[-1].retained == 0)
{
# ifdef OBJC_CAP_ARC
objc_delete_weak_refs(anObject);
# endif
pthread_mutex_unlock(theLock);
return YES;
}
Expand Down Expand Up @@ -947,6 +943,8 @@ + (void) load
{
#ifdef OBJC_CAP_ARC
_objc_weak_load = gs_weak_load;
#else
GSWeakInit();
#endif
objc_create_block_classes_as_subclasses_of(self);
}
Expand Down
4 changes: 4 additions & 0 deletions Source/ObjectiveC2/GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,11 @@ ObjectiveC2_OBJC_FILES += \
endif

ifeq ($(CC), clang)
# We need the flag for blocks support and we have ARC built in.
ADDITIONAL_OBJCFLAGS = -fblocks
else
# We need to emulated the weak reference API from the ARC runtime.
ObjectiveC2_OBJC_FILES += weak.m
endif

-include Makefile.preamble
Expand Down
10 changes: 5 additions & 5 deletions Source/ObjectiveC2/README
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ObjectiveC2 framework implements the new Apple runtime APIs, introduced with
OS X 10.5 on top of the GCC Objective-C runtime. Its use is now discouraged.
This code has been merged into the GNUstep Objective-C-2.0 runtime, which can
act as a drop-in replacement for GCC libobjc. You can find the code here:

svn://svn.gna.org/svn/gnustep/libs/libobjc2/trunk
OS X 10.5 (and later) on top of the GCC Objective-C runtime. Much code has
been merged into the GNUstep Objective-C-2.0 runtime, which is used when
compiling with clang (svn://svn.gna.org/svn/gnustep/libs/libobjc2/trunk).
Somewhat recent versions of the GNU runtime implement much of the newer Apple
APIs.
Loading

0 comments on commit 927e97e

Please sign in to comment.