в <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 байта в длину.
Вопрос явно не показывает его, но под 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-байтовые выровненные блоки.
Других решений пока нет …