私はASMライブラリを使ってバイトコードを生成し、Unsafe.defineAnonymous
をクラスとしてロードします。どちらもほとんどの場合に機能しますが、しばらくしてから失敗します。次に、出力されたバイトコードに何らかのデバッグ命令を追加して何かを出力し、出力が2週間混乱させました。Javaバイトコード変数インデックス0のclassNameが異常です
(GWTはGuardWithTestHandleの略です)
1、DYNGWT70とDYNGWT73の2つのクラスが生成され、両方ともUnsafe
を使用してロードされます。各クラスに対して、インスタンスが1つだけ作成されます。
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は同様の構造を有する: は、DYNGWT70のレイアウトのようなものです。
しかし、最初tempDebugための出力です:私はmh.getClass().getName()
がjava.lang.invoke.DYNGuardWithTestHandle73/0000000052DFAE40
であることを理解することはできません
___________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
、それが何かDYNGuardWithTestHandle**70**/0000000052DFAExxx
である必要があり、ここでスタックを掲示する目的は、それがDYN70のメソッドの実行中であることを示すことです例外は混乱している点に関連しています。
頻度は高いものの、このエラーは必ずしも発生しません。誰もが似たような奇妙なケースを経験しましたか?あなたの提案をありがとう。
エラーですか?あなたの期待と現実との違いは? – EJP
これはデバッグ文だけです。インデックス0の変数は、** DYNGuardWithTestHandle70 **である必要があります。ここでは73なので、DYNGWT70でしか動作しない後のメソッド呼び出し命令にエラーが発生します。 –
私は 'MethodHandle'のカスタムサブクラスを作成することをお勧めします。それはトラブルを求めるようなものです。生成されたコードにダイレクト・ハンドルを使用し、JVMにインライン展開をさせるというクリーンな方法と比べて、意味がありません。そしてそれはあなたがフォーカスを失う原因になります。例外は、1つのシグネチャにのみ存在する 'long'パラメータを示します。これはもちろん矛盾した型です。 – Holger