I'm looking into some Android performance issues at the moment and noticing some sub-optimal patterns in the dex code. I'm just wondering if anyone knows if this is to be expected, and what the rationale behind it might be.
For example, consider the following Java code:
m_testField += i;
doSomething(m_testField);
When this is built and then run through baksmali it looks like the following:
iget v1, p0, Lcom/example/MainActivity$FieldTest;->m_testField:I
add-int/2addr v1, v0
iput v1, p0, Lcom/example/MainActivity$FieldTest;->m_testField:I
iget v1, p0, Lcom/example/MainActivity$FieldTest;->m_testField:I
invoke-direct {p0, v1}, Lcom/example/MainActivity$FieldTest;->doSomething(I)V
The part that's concerning me is the iget opcode to read the value of the instance field into register v1. The same field was written from the very same v1 register in the preceding opcode, so the opcode would appear to be completely redundant.
The only thing I can think of is that this is done to make this more thread-safe. But surely that should be the programmer's responsibility (by using sync blocks) instead of the compiler's responsibility. Although I'm not 100% certain, I think the above behaviour is quite different to what most C/C++ compilers would do.
I should say that essentially the same dex is produced when ProGuard is used. I should also probably mention that I'm using the very latest Android tools and a late model JDK.