如何解决``getfield``指令?

时间:2018-03-26 14:14:55

标签: java jvm bytecode instruction-set bytecode-manipulation

好吧,我有一个Foo的实例,其中包含一个Object字段obj,以及一堆其他字段。

我现在创建一个班级Bar并为其提供Foo所有的字段以及一些额外的字段。特别是,Bar也有obj

我修改我的课程以使用Bar代替Foo,并让他们检测何时提交了Foo的实例并让他们将其转换为Bar的实例{1}}(如创建一个包含旧信息的新实例)。

快速检查确认Bar的新实例具有非空成员obj

到目前为止,非常好。

我现在称之为曾使用Foo的方法,现在使用Bar。另一项检查确认我们确实使用的是Bar版本的字节码,而不是旧版本。

查看字节码,我们看到了

getfield    Field Foo.obj:"Ljava/lang/Object;";

已更改为

getfield    Field Bar.obj:"Ljava/lang/Object;";

然而getfield正在返回null。 (或者主要是返回null,在极少数情况下,它会返回存储在其他字段中的另一个对象,或者甚至在极少数情况下可能会发生段错误。)

对我而言,这看起来像是一个错误的偏移计算。

如果是这样,我应该可以通过将getfield替换为使用正确偏移的Unsafe.getObject来绕过此问题。

但在此之前,我想确认这是可能的。 wikipedia表示

  

该字段由常量池中的字段引用标识

很好,但这并没有告诉我在识别后会发生什么。

Oracle指定

  

该索引处的运行时常量池项必须是对字段(第5.1节)的符号引用,该字段提供字段的名称和描述符以及字段所在的类的符号引用。被发现。

然后

  

引用的字段已解决(第5.4.3.2节)。获取objectref中引用字段的值

但即便that paragraph只是说

  

声明的字段是字段查找的结果。

“抓取”实际上是如何发生的?

0 个答案:

没有答案