나는 바이트 코드를 생성하고 클래스로 Unsafe.defineAnonymous
을 사용하여로드하기 위해 ASM 라이브러리를 사용한다. 둘 다 대부분의 경우 작동하지만 잠시 후 실패합니다. 그런 다음 출력 된 바이트 코드에 디버그 명령어를 추가하여 출력하고 출력 결과를 2 주 동안 혼란스럽게 만들었습니다.자바 바이트 코드 변수 인덱스 0의 className이 이상하다
(GWT는 GuardWithTestHandle의 약자입니다.)
1, DYNGWT70 및 DYNGWT73의 두 클래스가 생성되고 모두 Unsafe
을 사용하여로드됩니다. 각 클래스에 대해 하나의 인스턴스 만 만들어집니다.
public class java.lang.invoke.DYNGuardWithTestHandle70 extends java.lang.invoke.BaseTemplate{
public org.jruby.runtime.builtin.IRubyObject inlinedMethod(org.jruby.runtime.ThreadContext, org.jruby.runtime.builtin.IRubyObject, org.jruby.runtime.builtin.IRubyObject) throws java.lang.Throwable;
flags: ACC_PUBLIC
Code:
stack=8, locals=22, args_size=4
0: aload_0
1: aload_0
2: ldc #29 // String This is Guard java/lang/invoke/DYNGuardWithTestHandle70
4: invokestatic #32 // Method java/lang/invoke/BaseTemplate.tempDebug:(Ljava/lang/invoke/MethodHandle;Ljava/lang/String;)V
7: astore 4
9: aload 4
.....
}
}
protected static void tempDebug(MethodHandle mh, String name){
System.err.println("___________Debug: "+mh.getClass().getName()+", "+mh.toString()+ " message="+name);
}
DYNGWT73 비슷한 구조를 가지고 :
2
는 DYNGWT70의 레이아웃은 같은 것입니다.그러나 처음 tempDebug의 출력은 다음과 같습니다
___________Debug: java.lang.invoke.DYNGuardWithTestHandle73/0000000052DFAE40, MethodHandle(ThreadContext,IRubyObject,IRubyObject)IRubyObject uid:9a7bf505-8845-4594-9cf8-69f392eef869 message= This is Guard java/lang/invoke/DYNGuardWithTestHandle70
......
16/Aug/2016:22:13:42:834 -0300 [main] DEBUG java.lang.invoke.BaseTemplate - TypeInconsistException [_mh=MethodHandle(ThreadContext,IRubyObject,IRubyObject)IRubyObject uid:e064b157-f615-4f20-b386-947fc20c61ad, _exce=***** false (Lorg/jruby/runtime/ThreadContext;Lorg/jruby/runtime/builtin/IRubyObject;Lorg/jruby/runtime/builtin/IRubyObject;)Lorg/jruby/runtime/builtin/IRubyObject; (Lorg/jruby/runtime/ThreadContext;Lorg/jruby/runtime/builtin/IRubyObject;Lorg/jruby/runtime/builtin/IRubyObject;J)Lorg/jruby/runtime/builtin/IRubyObject;]
TypeInconsistException [_mh=MethodHandle(ThreadContext,IRubyObject,IRubyObject)IRubyObject uid:e064b157-f615-4f20-b386-947fc20c61ad, _exce=***** false (Lorg/jruby/runtime/ThreadContext;Lorg/jruby/runtime/builtin/IRubyObject;Lorg/jruby/runtime/builtin/IRubyObject;)Lorg/jruby/runtime/builtin/IRubyObject; (Lorg/jruby/runtime/ThreadContext;Lorg/jruby/runtime/builtin/IRubyObject;Lorg/jruby/runtime/builtin/IRubyObject;J)Lorg/jruby/runtime/builtin/IRubyObject;]
at java.lang.invoke.BaseTemplate.debugCompareReceiverTypeMethodDesc(BaseTemplate.java:59)
at java.lang.invoke.DYNGuardWithTestHandle70.0000000052B50680.inlinedMethod(Unknown Source)
at java.lang.invoke.DYNGuardWithTestHandle70.0000000052B50680.invokeExact_thunkArchetype_L(Unknown Source)
at java.lang.invoke.MutableCallSiteDynamicInvokerHandle.invokeExact_thunkArchetype_X(MutableCallSiteDynamicInvok
내가 mh.getClass().getName()
을 이해할 수는 java.lang.invoke.DYNGuardWithTestHandle73/0000000052DFAE40
, 그것은 여기 스택을 게시의 목적은이 DYN70의 방법을 실행하는 것을 보여주기 위해 뭔가 DYNGuardWithTestHandle**70**/0000000052DFAExxx
해야한다 예외는 혼란스러운 지점과 관련이 있습니다.
빈도는 높지만이 오류는 항상 발생하는 것은 아닙니다. 누구나 비슷한 이상한 사건을 경험 한 적이 있습니까? 귀하의 제안에 감사드립니다.
오류가 있습니까? 또는 당신의 기대와 현실 사이의 단지 차이? – EJP
이것은 디버그 명령문입니다. 인덱스가 0 인 변수는 ** DYNGuardWithTestHandle70 **이어야합니다. 여기에서 73이므로 DYNGWT70에서만 작동하는 나중의 메소드 호출 명령어에서 오류가 발생합니다. –
나는'MethodHandle'의 커스텀 서브 클래스를 만드는 것이 좋은 생각이라고 생각하지 않습니다. 그것은 문제를 요구하는 것과 같습니다. 그리고 생성 된 코드에 직접 핸들을 사용하고 JVM이 인라이닝을 수행하는 깔끔한 대안과 비교할 때 이치에 맞지 않습니다. 그리고 그것은 당신이 초점을 잃게 만듭니다. 이 예외는 '긴'매개 변수가 하나의 서명에만 존재 함을 나타내며, 이는 일관성없는 유형입니다. – Holger