java - JVM invokeinterface without type information -


i'm generating code java asm5 , wondering, why can invoke interface method on parameter, declared of type java/lang/object.

methodvisitor mv = cw.visitmethod(acc_public | acc_static, "test", "(ljava/lang/object;)v", null, null); mv.visitvarinsn(aload, 0); mv.visitinsn(dup); mv.visitmethodinsn(invokeinterface, "org/mydomain/foo", "foo", "()v", true); mv.visitmethodinsn(invokeinterface, "org/mydomain/bar", "bar", "()v", true); mv.visitinsn(return); mv.visitmaxs(-1,-1); mv.visitend(); 

generally have expected code require additional cast before invoking method ensure, object implements interface. safe call method without additional cast, long guarantee object implements interface or can run pitfalls? type checking of vm doesn't seem care it. if invoke object, doesn't implement interface java.lang.incompatibleclasschangeerror, not surprising. maybe have performance loss?

you encountered known sloppiness of hotspot’s verifier, not verify type compatibility of receiver types invokeinterface calls. not imply such code formally correct.

jvmspec, §4.9.2 structural constraints states:

  • the type of every class instance target of method invocation instruction must assignment compatible class or interface type specified in instruction (jls §5.2).

however, there practical problem verifying constraint statically verifiers of older jvms following algorithm called “verification type inference” , still standard class files having version below 50. this answer explains issue. if 2 different reference types have merged after branches, may result in common super type not implementing interface while both types do. rejecting subsequent invokeinterface call lead in rejecting correct code.

starting version 50, there “verification type checking”, mandatory versions higher 50. uses stackmap tables, explicitly declaring supposed result of type merging, eliminating expensive operations. consequently, “verification type checking” has formal rules mandate static type compatible interface type:

invokeinterface

an invokeinterface instruction type safe iff of following conditions hold:

  • one can validly replace types matching type methodintfname , argument types given in descriptor on incoming operand stack return type given in descriptor, yielding outgoing type state.

(note these rules identical the rules of invokevirtual instruction, except uses methodintfname instead of methodclassname)

as side note, code correct in environment java/lang/object happens implement both, org/mydomain/foo , org/mydomain/bar. it’s verification against actual environment missing here.

to put straight, code happens work on hotspot due missing check, not portable, i.e. may fail on other jvms , may fail on future versions of hotspot, type checking rules enforced.

there no performance advantage in omitting checkcast, there check 1 way or other , throwable thrown if type doesn’t match. therefore, stick creating formally correct code, if particular jvm not enforce it.


Comments

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -