Android — почему Dalvik Monitor выровнен по 8-байтовой границе

в <code root>/dalvik/vm/Sync.cpp, Eсть struct Monitor:

struct Monitor {
Thread*     owner;          /* which thread currently owns the lock? */
int         lockCount;      /* owner's recursive lock depth */
Object*     obj;            /* what object are we part of [debug only] */

Thread*     waitSet;    /* threads currently waiting on this monitor */

pthread_mutex_t lock;

Monitor*    next;

/*
* Who last acquired this monitor, when lock sampling is enabled.
* Even when enabled, ownerMethod may be NULL.
*/
const Method* ownerMethod;
u4 ownerPc;
};

Я не могу понять почему Monitor выравнивается на 8 байтов. Я думаю, что он должен быть выровнен на 4 байта, потому что все члены в нем (то есть указатель, int & pthread_mutex_t) 4 байта в длину.

2

Решение

Вопрос явно не показывает его, но под 8-байтовым выравниванием вы, вероятно, подразумеваете эту часть код, с Misaligned monitor проверять:

Monitor* dvmCreateMonitor(Object* obj)
{
Monitor* mon;
mon = (Monitor*) calloc(1, sizeof(Monitor));
if (mon == NULL) {
ALOGE("Unable to allocate monitor");
dvmAbort();
}
if (((u4)mon & 7) != 0) {
ALOGE("Misaligned monitor: %p", mon);
dvmAbort();
}

Причина в том, что Dalvik использует тонкую блокировку. Блокировка — это 32-битное значение объекта, а нижние 3 бита используются для кодирования состояния блокировки: один бит для состояния тонкой / полной блокировки и два бита для состояния хеша. Осталось только 29 бит для указателя на Monitor сам.

Из того же источник:

Само значение блокировки хранится в Object.lock. LSB из
Блокировка кодирует свое состояние. Когда очищено, блокировка находится в «тонком» состоянии, и ее биты отформатированы следующим образом:

[31 ---- 19] [18 ---- 3] [2 ---- 1] [0]
lock count   thread id  hash state  0

Когда установлено, блокировка находится в «толстом» состоянии, и ее биты отформатированы
следующее:

 [31 ---- 3] [2 ---- 1] [0]
pointer   hash state  1

Для справки вот статья с описанием тонкой блокировки: Тонкие блокировки: легковесная синхронизация для Java

В комментариях вы спрашиваете, как выполняется выравнивание. Стандарт C просто требует, чтобы распределители возвращали адрес, который может использоваться в любом типе назначения. От C99 §7.20.3 (Функции управления памятью):

Указатель, возвращаемый в случае успешного выделения, выравнивается соответствующим образом, чтобы его можно было присвоить указателю на объект любого типа, а затем использовать для доступа к такому объекту или массиву таких объектов в выделенном пространстве (пока пространство не будет явно освобождено) ,

По умолчанию, malloc/calloc/realloc в 32-битной системе ARM вернуть 8-байтовые выровненные блоки. Я верю Misaligned monitor проверка заключается в том, что защитный код быстро сбой в случае замены распределителя на версию, которая не возвращает 8-байтовые выровненные блоки.

3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector