简体   繁体   English

是否为“此”访问权限发出空检查?

[英]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: 当您通过引用访问自己的实例字段(例如,私有方法中的objectint字段)时,生成的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM