Skip to content

Commit

Permalink
fix(blocks runtime): Optimise determination of whether something is a…
Browse files Browse the repository at this point in the history
… block in ARC
  • Loading branch information
ngrewe committed Jun 2, 2024
1 parent 5e7d65c commit 7edfecc
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 23 deletions.
11 changes: 11 additions & 0 deletions NSBlocks.m
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ static void createNSBlockSubclass(Class superclass, Class newClass,
newClass->super_class = superclass;
newClass->name = name;
newClass->dtable = uninstalled_dtable;
newClass->info = objc_class_flag_is_block;

LOCK_RUNTIME_FOR_SCOPE();
objc_load_class(newClass);
Expand All @@ -66,3 +67,13 @@ BOOL objc_create_block_classes_as_subclasses_of(Class super)
objc_class_flag_permanent_instances);
return YES;
}

PRIVATE void init_early_blocks(void)
{
if (_NSBlock.super_class != NULL) { return; }
_NSConcreteStackBlock.info = objc_class_flag_is_block;
_NSConcreteGlobalBlock.info = objc_class_flag_is_block | objc_class_flag_permanent_instances;
_NSConcreteMallocBlock.info = objc_class_flag_is_block;
_NSConcreteAutoBlock.info = objc_class_flag_is_block;
_NSConcreteFinalizingBlock.info = objc_class_flag_is_block;
}
35 changes: 12 additions & 23 deletions arc.mm
Original file line number Diff line number Diff line change
Expand Up @@ -325,12 +325,7 @@ static inline id retain(id obj, BOOL isWeak)
{
if (isPersistentObject(obj)) { return obj; }
Class cls = obj->isa;
if ((Class)&_NSConcreteMallocBlock == cls ||
(Class)&_NSConcreteStackBlock == cls ||
(Class)&_NSConcreteAutoBlock == cls ||
(Class)&_NSConcreteFinalizingBlock == cls
)
{
if (UNLIKELY(objc_test_class_flag(cls, objc_class_flag_is_block))) {
return Block_copy(obj);
}
if (objc_test_class_flag(cls, objc_class_flag_fast_arc))
Expand Down Expand Up @@ -389,17 +384,15 @@ static inline void release(id obj)
{
if (isPersistentObject(obj)) { return; }
Class cls = obj->isa;
if (cls == static_cast<void*>(&_NSConcreteMallocBlock) ||
cls == static_cast<void*>(&_NSConcreteAutoBlock) ||
cls == static_cast<void*>(&_NSConcreteFinalizingBlock))
if (UNLIKELY(objc_test_class_flag(cls, objc_class_flag_is_block)))
{
if (cls == static_cast<void*>(&_NSConcreteStackBlock))
{
return;
}
_Block_release(obj);
return;
}
if (cls == static_cast<void*>(&_NSConcreteStackBlock))
{
return;
}
if (objc_test_class_flag(cls, objc_class_flag_fast_arc))
{
objc_release_fast_np(obj);
Expand Down Expand Up @@ -871,10 +864,7 @@ static BOOL setObjectHasWeakRefs(id obj)
return obj;
}
Class cls = classForObject(obj);
if (cls == static_cast<void*>(&_NSConcreteMallocBlock) ||
cls == static_cast<void*>(&_NSConcreteAutoBlock) ||
cls == static_cast<void*>(&_NSConcreteFinalizingBlock))
{
if (UNLIKELY(objc_test_class_flag(cls, objc_class_flag_is_block))) {
// Check whether the block is being deallocated and return nil if so
if (_Block_isDeallocating(obj)) {
*addr = nil;
Expand Down Expand Up @@ -954,15 +944,14 @@ static BOOL setObjectHasWeakRefs(id obj)
return nil;
}
Class cls = classForObject(obj);
if (static_cast<void*>(&_NSConcreteMallocBlock) == cls ||
static_cast<void*>(&_NSConcreteAutoBlock) == cls ||
static_cast<void*>(&_NSConcreteFinalizingBlock) == cls) {
obj = static_cast<id>(block_load_weak(obj));
}
else if (objc_test_class_flag(cls, objc_class_flag_permanent_instances))
if (objc_test_class_flag(cls, objc_class_flag_permanent_instances))
{
return obj;
}
else if (UNLIKELY(objc_test_class_flag(cls, objc_class_flag_is_block))) {
obj = static_cast<id>(block_load_weak(obj));
}

else if (!objc_test_class_flag(cls, objc_class_flag_fast_arc))
{
obj = _objc_weak_load(obj);
Expand Down
5 changes: 5 additions & 0 deletions class.h
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,11 @@ enum objc_class_flags
* On a class, guarantees that `+init` is trivial.
*/
objc_class_flag_fast_alloc_init = (1<<15),
/**
* The class is a block class. Reference count management must be done by
* the underlying blocks runtime.
*/
objc_class_flag_is_block = (1 << 16),
};

/**
Expand Down
2 changes: 2 additions & 0 deletions loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ void init_gc(void);
void init_protocol_table(void);
void init_selector_tables(void);
void init_trampolines(void);
void init_early_blocks(void);
void objc_send_load_message(Class class);

void log_selector_memory_usage(void);
Expand Down Expand Up @@ -76,6 +77,7 @@ static void init_runtime(void)
init_protocol_table();
init_class_tables();
init_alias_table();
init_early_blocks();
init_arc();
init_trampolines();
first_run = NO;
Expand Down

0 comments on commit 7edfecc

Please sign in to comment.