[英]Null check emitted for 'this' access?
When you access an own instance field via the this reference (for example, an object
or int
field from a private method), the generated Android Dalvik bytecode will contain an iget
bytecode instruction: 当您通过此引用访问自己的实例字段(例如,私有方法中的object
或int
字段)时,生成的Android Dalvik字节码将包含iget
字节码指令:
iget v2, p0, Lcom/example/myapp/MyClass;->status:I
This is the same instruction which is emitted when you access another object's field (ie not via the this
pointer), so it doesn't seem to distinguish between other objects and yourself. 这与您访问另一个对象的字段(即不通过this
指针)时发出的指令相同,因此似乎无法区分其他对象和您自己。 In bytecode, this is understandable, but the JIT could do more. 在字节码中,这是可以理解的,但是JIT可以做更多的事情。
Checking the Android source code, I don't see that the null check is automatically eliminated by the JIT for such cases (ie when you access this
). 在检查Android源代码时,我没有看到在这种情况下(即,当您访问this
)JIT会自动消除空检查。 It is eliminated in basic blocks for already-null-checked Dalvik registers, fine, but (to me) it seems it could also be eliminated for the this
access (even if it's the first instruction of a basic block, or any instruction, as this
cannot be null). 对于已经为空检查的Dalvik寄存器,可以在基本块中删除它,这很好,但是(对我而言)似乎也可以在this
访问中删除(即使它是基本块的第一条指令或任何指令,例如this
不能为null)。
What am I missing? 我想念什么? Is it for security/runtime typesafety reasons? 是出于安全性/运行时类型安全性的原因吗? Or I simply overlook the source code? 还是我只是忽略了源代码? Why cannot the VM (JIT) handle this
in a distinguished way? 为什么VM(JIT)无法以独特的方式处理this
问题? (I understand native code obviously can't, because this
is a memory address just like anything else.) (我知道本机代码显然不能,因为this
和其他任何东西一样是一个内存地址。)
EDIT: as far as I can see, "already-null-checked" flags are cleared each time a basic block ends in the dvm. 编辑:据我所知,每当基本块在dvm中结束时,都会清除“已经空检查”标志。 What I'm saying is that the "already-null-checked" flag for registers which hold this could be pre-set to 1 (and the value would not need to be cleared even during transitions between basic blocks). 我要说的是,可以将保存该寄存器的寄存器的“已经为空检查”标志预先设置为1(并且即使在基本块之间进行转换时也不需要清除该值)。
From the bytecode's perspective, accessing fields on the "this" object is no different than accessing them on any other object - you still have to pass in a register that contains the "this" reference. 从字节码的角度来看,访问“ this”对象上的字段与访问任何其他对象上的字段没有什么不同-您仍然必须传入包含“ this”引用的寄存器。 Since there's no way to guarantee that the register being passed in will actually contain a non-null value, it still has to perform the nullness check, just like for any other object. 由于无法保证传入的寄存器实际上包含一个非空值,因此它仍然必须执行空值检查,就像对其他任何对象一样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.