#objective-c #exception #automatic-ref-counting
#objective-c #исключение #автоматический подсчет ссылок
Вопрос:
Рассмотрим следующие простые функции:
void simple_throw(id object) {
@throw object;
}
void extra_throw(id object) {
id tmp0 = object;
id tmp1 = tmp0;
id tmp2 = tmp1;
@throw tmp2;
}
Изначально я думал, что обе эти функции должны компилироваться в одну сборку, и обе должны быть эквивалентны простому вызову objc_exception_throw(object)
(поскольку аргументы функции по умолчанию autorelease
находятся в ARC), возможно, с одним objc_retain(object)
добавлением (поскольку ARC не является безопасным для исключений и по умолчанию имеет утечку).
Но это не так. Вот сборка (удаление некоторых дополнительных пух и .cfi_*
директив; аргументы clang: -fobjc-arc -Ofast -fomit-frame-pointer -S
):
_simple_throw:
pushq %rax
callq *_objc_retain@GOTPCREL(%rip)
movq %rax, %rdi
callq _objc_retainAutorelease
movq %rax, %rdi
callq _objc_exception_throw
_extra_throw:
pushq %rbx
movq _objc_retain@GOTPCREL(%rip), %rbx
callq *%rbx
movq %rax, %rdi
callq *%rbx
movq %rax, %rdi
callq *%rbx
movq %rax, %rdi
callq *%rbx
movq %rax, %rdi
callq _objc_retainAutorelease
movq %rax, %rdi
callq _objc_exception_throw
simple_throw
сохраняет object
дважды и extra_throw
сохраняет object
5 раз!
Это приводит к двум вопросам:
- Какова оптимальная сборка (с точки зрения сохранения и автоматического освобождения), для
simple_throw
которой компилятор должен генерировать (предполагая, что мы хотим, чтобы сгенерированный код был совместим с ARC)? - Почему присвоения локальным переменным в
extra_throw
приводят к дополнительным сохранениям? Я склонен думать, что это ошибка компилятора.
Комментарии:
1. Как бы то ни было, он делает то же самое, если вы заменяете
@throw
операторы вызовамиnoreturn
функции. Кажется, что ошибка.2. Я думаю, что обычно он добавляет соответствующие вызовы release в конце области видимости локальных переменных / параметров, а проход оптимизации удаляет избыточные пары. Операторы no-return препятствуют достижению «естественного» конца области видимости, поэтому они просто отбрасываются, и сохранение не может быть оптимизировано.
3. Это кажется очень правдоподобным!