ОБНОВЛЕНО со значительной новой информацией (см. Внизу)
ИЗМЕНЕНО с улучшенным кодом регистрации
Я отслеживаю некоторые графические искажения в нашем приложении и отследил их до этой функции (котораяЯ обильно обсыпал ведение журнала):
public final int p_PostDraw(){
bb_std_lang.print("Dissolve encountered.");
float t_d=c_GColour.m_dissolve;
bb_std_lang.print("Cached dissolve value locally: "+c_GColour.m_dissolve+ " " + t_d);
c_GColour.m_dissolve=c_Gel.m_colstack.p_Top().m_a;
bb_std_lang.print("Updated dissolve value: " + c_GColour.m_dissolve);
c_Gel.m_colstack.p_Top().m_a=1.0f;
bb_std_lang.print("Monitoring t_d="+t_d);
super.p_PostDraw();
bb_std_lang.print("Monitoring t_d="+t_d);
c_GColour.m_dissolve=t_d;
bb_std_lang.print("Dissolve post restore " + c_GColour.m_dissolve);
return 0;
}
Большую часть времени это работает, как и ожидалось, но в определенный момент в игре это записывается:
09-30 14:40:59.086 10545-11101/? I/[Monkey]: Dissolve encountered.
09-30 14:40:59.086 10545-11101/? I/[Monkey]: Cached dissolve value locally: 1.0 1.0
09-30 14:40:59.086 10545-11101/? I/[Monkey]: Updated dissolve value: 0.1
09-30 14:40:59.086 10545-11101/? I/[Monkey]: Monitoring t_d=1.0
09-30 14:40:59.087 10545-11101/? I/[Monkey]: Monitoring t_d=-1.6314132E-19
09-30 14:40:59.087 10545-11101/? I/[Monkey]: Dissolve post restore -1.6314132E-19
Чтобы сломатьэто для вас: статическое значение m_dissolve копируется в локальную переменную t_d и имеет значение 1.0f. Статическое значение затем изменяется на 0,1f и используется при рендеринге дочерних объектов. Когда это будет завершено, локальная переменная t_d снова регистрируется перед использованием для восстановления статического значения, но тем временем таинственным образом становится -1.6314132E-19 (это значение кажется непредсказуемо разным каждый раз).
Мне неизвестно, каким образом локальная переменная Java может быть повреждена таким образом.
ОБНОВЛЕНИЕ:
В качестве теста я сделалt_d - переменная-член класса, содержащая приведенный выше код (а не локальную переменную), и ее значение больше не повреждено.
В качестве дополнительного теста я затем добавил несколько локальных переменных с плавающей запятой (от m_e до m_j)которые использовались ни для чего, кроме распечатки до и после super.p_PostDraw (). Вот что произошло:
09-30 15:20:51.219 28384-28877/? I/[Monkey]: M_E ETC BEFORE: 1.0 1.0 1.0 1.0 1.0 1.0
09-30 15:20:51.220 28384-28877/? I/[Monkey]: M_E ETC AFTER: 6.7E-44 6.7E-44 6.7E-44 6.7E-44 6.7E-44 6.7E-44
Затем я удалил все фильтры из logcat и обнаружил, что это скрывается между этими двумя строками:
09-30 15:20:51.219 28384-28877/? I/[Monkey]: M_E ETC BEFORE: 1.0 1.0 1.0 1.0 1.0 1.0
09-30 15:20:51.220 28384-28877/? I/zygote64: Deoptimizing int app.hidden.name.c_IffLT.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:20:51.220 28384-28877/? I/zygote64: Deoptimizing int app.hidden.name.c_Delay.p_Pump2(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:20:51.220 28384-28877/? I/zygote64: Deoptimizing int app.hidden.name.c_SetUniform_4F.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:20:51.220 28384-28877/? I/zygote64: Deoptimizing int app.hidden.name.c_EX_VarString.p_Set7(app.hidden.name.c_Expression) due to JIT inline cache
09-30 15:20:51.220 28384-28877/? I/zygote64: Deoptimizing java.lang.String app.hidden.name.c_EX_Format.p_AsString() due to JIT inline cache
09-30 15:20:51.220 28384-28877/? I/zygote64: Deoptimizing int app.hidden.name.c_IffNotEqual.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:20:51.220 28384-28877/? I/zygote64: Deoptimizing int app.hidden.name.c_PinVP.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:20:51.220 28384-28877/? I/[Monkey]: M_E ETC AFTER: 6.7E-44 6.7E-44 6.7E-44 6.7E-44 6.7E-44 6.7E-44
ОБНОВЛЕНИЕ:
Я настроил приведенный выше код для установки локальных переменных на разные значения, а не на все 1.0f, и это произошло:
09-30 15:56:37.686 1815-2373/? I/[Monkey]: M_E BEFORE: 2.0 1.0 3.0 4.0 5.0 1.0
09-30 15:56:37.687 1815-2373/? I/zygote64: Deoptimizing int app.hidden.name.c_IffLT.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:56:37.687 1815-2373/? I/zygote64: Deoptimizing int app.hidden.name.c_Delay.p_Pump2(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:56:37.687 1815-2373/? I/zygote64: Deoptimizing int app.hidden.name.c_SetUniform_4F.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:56:37.687 1815-2373/? I/zygote64: Deoptimizing int app.hidden.name.c_EX_VarString.p_Set7(app.hidden.name.c_Expression) due to JIT inline cache
09-30 15:56:37.688 1815-2373/? I/zygote64: Deoptimizing java.lang.String app.hidden.name.c_EX_Format.p_AsString() due to JIT inline cache
09-30 15:56:37.688 1815-2373/? I/zygote64: Deoptimizing int app.hidden.name.c_IffNotEqual.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:56:37.688 1815-2373/? I/zygote64: Deoptimizing int app.hidden.name.c_PinVP.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:56:37.688 1815-2373/? I/[Monkey]: M_E AFTER: 2.0 -5.6063644E-30 3.0 4.0 5.0 -5.6063644E-30
Другими словами, только локальная переменная, установленная на 1.0f, былаповрежден. Не первый объявленный или что-то еще, просто тот, который установлен на 1.0f. Затем я попытался установить все локальные переменные на разные номера ДРУГИЕ, чем 1.0f и не произошло искажения .
Конечно, должен быть какой-то приз за самую неясную ошибку в истории? Что локальная переменная будет повреждена, если ART деоптимизирует функции, но только если эта локальная переменная имеет значение 1,0?