¿Qué optimizaciones hizo Apple al puntero ISA de 64 bits y cómo mejoraron realmente el rendimiento?

La magia es (no, en realidad, así lo llama CLANG) es una optimización más formalmente conocida como puntero etiquetado. Debido a todo el espacio extra que ofrece un puntero en un espacio de direcciones de 64 bits (que de todos modos ni siquiera utiliza los 64 bits completos), los bits superiores se pueden reservar para contener datos arbitrarios. Apple ha aprovechado esta oportunidad, combinada con las actualizaciones recientes del tiempo de ejecución, para implementar NSNumber y Collection Literals comunes como punteros etiquetados. El tiempo de ejecución ahora tiene una serie de rutas rápidas configuradas para enmascarar el isa bit mágico (en este momento, el LSB) y leer los mensajes a estos objetos a pesar de que los punteros etiquetados técnicamente no son objetos. Si desea ver esto en acción, inicie LLDB e intente po (id) . Dados los números correctos, obtendrá un puntero etiquetado para un literal entero o dos.

La magia isa hace más que solo contar cuentas de referencia. Los bits superiores también almacenan indicadores de si un objeto tiene objetos asociados adjuntos, un destructor C ++ (si no, el tiempo de ejecución lo lee a través de otra ruta rápida durante la desasignación), bits para el depurador para distinguir objetos reales de basura no inicializada, si el objeto se desasigna, y si el objeto es lo suficientemente grande como para necesitar un suplemento de recuento de referencia lateral.

Por otro lado, si desea, hay dos formas válidas y una forma hack de deshabilitar punteros etiquetados. La primera es una variable de entorno, OBJC_DISABLE_NONPOINTER_ISA . El segundo es anular +allocWithZone: y configurar el puntero isa usted mismo. (Tenga en cuenta que invocar object_setClass() en este método mantiene la optimización habilitada). La última forma terrible es tomar un puntero etiquetado y establecer el LSB en cero, lo que hará que el tiempo de ejecución lo lea como un puntero normal y probablemente se bloquee y se queme.

Las versiones de iOS (y OSX) de Cocoa / Objective C usan un esquema de conteo de referencia para establecer si un objeto aún está vivo. Las llamadas de retención y liberación se realizan todo el tiempo. Por lo tanto, acelerarlos tendría un beneficio significativo.

Un uso del puntero de 64 bits es almacenar el recuento de referencia en los bits no utilizados del puntero.

Esto hace que el código de recuento de referencia sea mucho más compacto.

EDITAR (Gracias a Brent Royal-Gordon) –

Debido a que el recuento de referencia está escondido dentro del puntero, el número ya está en un registro de CPU. Entonces esto lo hace significativamente más rápido.