锘??xml version="1.0" encoding="utf-8" standalone="yes"?> www.bitsCN.com YOUR_LIB=your_path for jar in `ls $YOUR_LIB/*.jar`
緙栬瘧HelloWorld綾?br>
2 public native void displayHelloWorld();
3
4 public native void printxx(String str);
5
6 static {
7 System.loadLibrary("hello");
8 // System.load("hello");
9 }
10
11 public static void main(String[] args) {
12 HelloWorld hw = new HelloWorld();
13 hw.displayHelloWorld();
14 for (int i = 0;; ++i) {
15 hw
16 .printxx("wo kaowo kaowo kaowo kaowo kaowo kaowo kaowo kaowo kaowo kaowo kao");
17 if (i % 1000 == 0) {
18 try {
19 Thread.sleep(10);
20 } catch (InterruptedException e) {
21 }
22 }
23 }
24 }
25 }
瀵圭紪璇戝畬鐨刢lass鎵ц
javah HelloWorld
2 #include <jni.h>
3 /* Header for class HelloWorld */
4
5 #ifndef _Included_HelloWorld
6 #define _Included_HelloWorld
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10 /*
11 * Class: HelloWorld
12 * Method: displayHelloWorld
13 * Signature: ()V
14 */
15 JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
16 (JNIEnv *, jobject);
17
18 /*
19 * Class: HelloWorld
20 * Method: printxx
21 * Signature: (Ljava/lang/String;)V
22 */
23 JNIEXPORT void JNICALL Java_HelloWorld_printxx
24 (JNIEnv *, jobject, jstring);
25
26 #ifdef __cplusplus
27 }
28 #endif
29 #endif
30
緙栬瘧
cl -I%java_home%\include -I%java_home%\include\win32 -LDHelloWorld.c -Fehello.dll
2 #include "HelloWorld.h"
3 #include <stdio.h>
4 JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj)
5 {
6 printf("Hello world!\n");
7 return;
8 }
9
10 JNIEXPORT void JNICALL Java_HelloWorld_printxx
11 (JNIEnv *env, jobject obj, jstring prompt){
12
13 const char *str = (*env)->GetStringUTFChars(env, prompt, 0);
14 printf("%s",prompt);
15 (*env)->ReleaseStringUTFChars(env, prompt, str);
16
17 return;
18 }
19
20
3錛嶫ava綾誨瀷鍜屾湰鍦扮被鍨嬪搴?br>銆銆
銆銆鍦ㄥ涓嬫儏鍐典笅錛岄渶瑕佸湪鏈湴鏂規硶涓簲鐢╦ava瀵硅薄鐨勫紩鐢紝灝變細鐢ㄥ埌綾誨瀷涔嬮棿鐨勮漿鎹細
銆銆
銆銆1錛塲ava鏂規硶閲岄潰灝嗗弬鏁頒紶鍏ユ湰鍦版柟娉曪紱
銆銆
銆銆2錛夊湪鏈湴鏂規硶閲岄潰鍒涘緩java瀵硅薄錛?br>銆銆
銆銆3錛夊湪鏈湴鏂規硶閲岄潰return緇撴灉緇檍ava紼嬪簭銆?br>銆銆
銆銆鍒嗕負濡備笅涓ょ鎯呭喌錛?br>銆銆
銆銆Java鍘熷綾誨瀷
銆銆
銆銆鍍廱ooleans銆乮ntegers銆乫loats絳変粠Java紼嬪簭涓紶鍒版湰鍦版柟娉曚腑鐨勫師濮嬬被鍨嬪彲浠ョ洿鎺ヤ嬌鐢紝涓嬮潰鏄痡ava涓殑鍘熷綾誨瀷鍜屾湰鍦版柟娉曚腑鐨勭被鍨嬬殑瀵瑰簲錛?br>銆銆
銆銆Java綾誨瀷銆銆鏈湴綾誨瀷銆銆瀛楄妭(bit)
銆銆
銆銆boolean銆銆 jboolean銆銆 8, unsigned
銆銆byte銆銆銆銆jbyte銆銆銆銆8
銆銆char銆銆銆銆jchar銆銆銆銆16, unsigned
銆銆short銆銆銆 jshort銆銆銆 16
銆銆int銆銆銆銆 jint銆銆銆銆 32
銆銆long銆銆銆銆jlong銆銆銆銆64
銆銆float銆銆銆 jfloat銆銆銆 32
銆銆double銆銆銆jdouble銆銆銆64
銆銆void銆銆銆銆void銆銆銆銆 n/a
銆銆
銆銆涔熷氨鏄濡傛灉鎴戝湪鏂規硶涓紶榪涘幓浜嗕竴涓猙oolean鐨勫弬鏁扮殑璇濓紝閭d箞鎴戝湪鏈湴鏂規硶涓氨鏈塲boolean綾誨瀷涓庝箣瀵瑰簲銆傚悓鐞嗭紝濡傛灉鍦ㄦ湰鍦版柟娉曚腑return涓涓猨int鐨勮瘽錛岄偅涔堝湪java涓氨榪斿洖涓涓猧nt綾誨瀷銆?涓浗緗戠璁哄潧
銆銆
銆銆Java瀵硅薄
銆銆
銆銆Java瀵硅薄鍋氫負寮曠敤琚紶閫掑埌鏈湴鏂規硶涓紝鎵鏈夎繖浜汮ava瀵硅薄鐨勫紩鐢ㄩ兘鏈変竴涓叡鍚岀殑鐖剁被鍨媕object(鐩稿綋浜巎ava涓殑Object綾繪槸鎵鏈夌被鐨勭埗綾諱竴鏍?銆備笅闈㈡槸JNI瀹炵幇鐨勪竴浜沯object鐨勫瓙綾伙細
銆銆
銆銆4錛庢湰鍦版柟娉曚腑璁塊棶java紼嬪簭涓殑鍐呭
銆銆
銆銆1)璁塊棶String瀵硅薄錛?br>銆銆
銆銆浠巎ava紼嬪簭涓紶榪囧幓鐨凷tring瀵硅薄鍦ㄦ湰鍦版柟娉曚腑瀵瑰簲鐨勬槸jstring綾誨瀷錛宩string綾誨瀷鍜宑涓殑char*涓嶅悓錛屾墍浠ュ鏋滀綘鐩存帴褰撳仛char*浣跨敤鐨勮瘽錛屽氨浼氬嚭閿欍傚洜姝ゅ湪浣跨敤涔嬪墠闇瑕佸皢jstring杞崲鎴愪負c/c++涓殑char*錛岃繖閲屼嬌鐢↗NIEnv鐨勬柟娉曡漿鎹€備笅闈㈡槸涓涓緥瀛愶細
銆銆
銆銆浠g爜3錛?br>銆銆
銆銆JNIEXPORT jstring JNICALL Java_Prompt_getLine
銆銆(JNIEnv *env, jobject obj, jstring prompt)
銆銆{
銆銆char buf[128];
銆銆const char *str = (*env)->GetStringUTFChars(env, prompt, 0);
銆銆printf("%s", str);
銆銆(*env)->ReleaseStringUTFChars(env, prompt, str);
銆銆
銆銆榪欓噷浣跨敤GetStringUTFChars鏂規硶灝嗕紶榪涙潵鐨刾rompt錛坖string綾誨瀷錛夎漿鎹㈡垚涓篣TF錛?鐨勬牸寮忥紝灝辮兘澶熷湪鏈湴鏂規硶涓嬌鐢ㄤ簡銆?br>銆銆
銆銆娉ㄦ剰錛氬湪浣跨敤瀹屼綘鎵杞崲涔嬪悗鐨勫璞′箣鍚庯紝闇瑕佹樉紺鴻皟鐢≧eleaseStringUTFChars鏂規硶錛岃JVM閲婃斁杞崲鎴怳TF-8鐨剆tring鐨勫璞$殑絀洪棿錛屽鏋滀笉鏄劇ず鐨勮皟鐢ㄧ殑璇濓紝JVM涓細涓鐩翠繚瀛樿瀵硅薄錛屼笉浼氳鍨冨溇鍥炴敹鍣ㄥ洖鏀訛紝鍥犳灝變細瀵艱嚧鍐呭瓨婧㈠嚭銆?
銆銆
銆銆涓嬮潰鏄闂甋tring鐨勪竴浜涙柟娉曪細
銆銆
銆銆鈼咷etStringUTFChars灝唈string杞崲鎴愪負UTF-8鏍煎紡鐨刢har*
銆銆
銆銆鈼咷etStringChars灝唈string杞崲鎴愪負Unicode鏍煎紡鐨刢har*
銆銆
銆銆鈼哛eleaseStringUTFChars閲婃斁鎸囧悜UTF-8鏍煎紡鐨刢har*鐨勬寚閽?br>銆銆
銆銆鈼哛eleaseStringChars閲婃斁鎸囧悜Unicode鏍煎紡鐨刢har*鐨勬寚閽?br>銆銆
銆銆鈼哊ewStringUTF鍒涘緩涓涓猆TF-8鏍煎紡鐨凷tring瀵硅薄
銆銆
銆銆鈼哊ewString鍒涘緩涓涓猆nicode鏍煎紡鐨凷tring瀵硅薄
銆銆
銆銆鈼咷etStringUTFLengt鑾峰彇UTF-8鏍煎紡鐨刢har*鐨勯暱搴?br>銆銆
銆銆鈼咷etStringLength鑾峰彇Unicode鏍煎紡鐨刢har*鐨勯暱搴?br>銆銆
銆銆2) 璁塊棶Array瀵硅薄錛?br>銆銆
銆銆鍜孲tring瀵硅薄涓鏍鳳紝鍦ㄦ湰鍦版柟娉曚腑涓嶈兘鐩存帴璁塊棶jarray瀵硅薄錛岃屾槸浣跨敤JNIEnv鎸囬拡鎸囧悜鐨勪竴浜涙柟娉曟潵鏄敤銆?br>銆銆
銆銆璁塊棶Java鍘熷綾誨瀷鏁扮粍錛?br>銆銆
銆銆1錛夎幏鍙栨暟緇勭殑闀垮害錛?br>銆銆
銆銆浠g爜4錛?br>銆銆
銆銆JNIEXPORT jint JNICALL Java_IntArray_sumArray
銆銆(JNIEnv *env, jobject obj, jintArray arr)
銆銆{
銆銆int i, sum = 0;
銆銆jsize len = (*env)->GetArrayLength(env, arr);
銆銆
銆銆濡備唬鐮?鎵紺猴紝榪欓噷鑾峰彇鏁扮粍鐨勯暱搴﹀拰鏅氱殑c璇█涓殑鑾峰彇鏁扮粍闀垮害涓嶄竴鏍鳳紝榪欓噷浣跨敤JNIEvn鐨勪竴涓嚱鏁癎etArrayLength銆?
銆銆
銆銆2錛夎幏鍙栦竴涓寚鍚戞暟緇勫厓绱犵殑鎸囬拡錛?br>銆銆
銆銆浠g爜4錛?br>銆銆
銆銆jint *body = (*env)->GetIntArrayElements(env, arr, 0);
銆銆
銆銆浣跨敤GetIntArrayElements鏂規硶鑾峰彇鎸囧悜arr鏁扮粍鍏冪礌鐨勬寚閽堬紝娉ㄦ剰璇ュ嚱鏁扮殑鍙傛暟錛岀涓涓槸JNIEnv錛岀浜屼釜鏄暟緇勶紝絎笁涓槸鏁扮粍閲岄潰絎笁涓槸鏁扮粍閲岄潰寮濮嬬殑鍏冪礌
銆銆
銆銆3錛変嬌鐢ㄦ寚閽堝彇鍑篈rray涓殑鍏冪礌
銆銆
銆銆浠g爜5錛?br>銆銆
銆銆for (i=0; i<len; i++) {
銆銆sum += body[i];
銆銆}
銆銆
銆銆榪欓噷浣跨敤灝卞拰鏅氱殑c涓殑鏁扮粍浣跨敤娌℃湁浠涔堜笉鍚屼簡
銆銆
銆銆4錛夐噴鏀炬暟緇勫厓绱犵殑寮曠敤
銆銆
銆銆浠g爜6錛?br>銆銆
銆銆(*env)->ReleaseIntArrayElements(env, arr, body, 0);
銆銆
銆銆鍜屾搷浣淪tring涓殑閲婃斁String鐨勫紩鐢ㄦ槸涓鏍風殑錛屾彁閱扟VM鍥炴敹arr鏁扮粍鍏冪礌鐨勫紩鐢ㄣ?br>銆銆
銆銆榪欓噷涓劇殑渚嬪瓙鏄嬌鐢╥nt鏁扮粍鐨勶紝鍚屾牱榪樻湁boolean銆乫loat絳夊搴旂殑鏁扮粍銆?br>銆銆
銆銆鑾峰彇鏁扮粍鍏冪礌鎸囬拡鐨勫搴斿叧緋伙細
銆銆
銆銆鍑芥暟銆銆銆銆銆銆銆銆銆銆銆銆鏁扮粍綾誨瀷
銆銆
銆銆GetBooleanArrayElements銆銆 boolean
銆銆GetByteArrayElements銆銆銆銆byte
銆銆GetCharArrayElements銆銆銆銆char bitsCN.nET涓浗緗戠鍗氬
銆銆GetShortArrayElements銆銆銆 short
銆銆GetIntArrayElements銆銆銆銆 int
銆銆GetLongArrayElements銆銆銆銆long
銆銆GetFloatArrayElements銆銆銆 float
銆銆GetDoubleArrayElements銆銆銆double
銆銆
銆銆閲婃斁鏁扮粍鍏冪礌鎸囬拡鐨勫搴斿叧緋伙細
銆銆Function銆銆銆銆銆銆銆銆銆銆銆銆Array Type
銆銆ReleaseBooleanArrayElements銆銆 boolean
銆銆ReleaseByteArrayElements銆銆銆銆byte
銆銆ReleaseCharArrayElements銆銆銆銆char
銆銆ReleaseShortArrayElements銆銆銆 short
銆銆ReleaseIntArrayElements銆銆銆銆 int
銆銆ReleaseLongArrayElements銆銆銆銆long
銆銆ReleaseFloatArrayElements銆銆銆 float
銆銆ReleaseDoubleArrayElements銆銆銆double
銆銆
銆銆璁塊棶鑷畾涔塉ava瀵硅薄鏁扮粍
銆銆
銆銆The JNI provides a separate set of functions to access elements of object arrays. You can use these functions to get and set individual object array elements.
銆銆
銆銆Note:銆You cannot get all the object array elements at once.
銆銆
銆銆GetObjectArrayElement returns the object element at a given index.
銆銆
銆銆SetObjectArrayElement updates the object element at a given index.
銆銆
銆銆3) 璁塊棶Java瀵硅薄鐨勬柟娉曪細
銆銆
銆銆鍦ㄦ湰鍦版柟娉曚腑璋冪敤Java瀵硅薄鐨勬柟娉曠殑姝ラ錛?br>銆銆
銆銆鈶?鑾峰彇浣犻渶瑕佽闂殑Java瀵硅薄鐨勭被錛?br>銆銆
銆銆jclass cls = (*env)->GetObjectClass(env, obj);
銆銆
銆銆浣跨敤GetObjectClass鏂規硶鑾峰彇obj瀵瑰簲鐨刯class銆?br>銆銆
銆銆鈶?鑾峰彇MethodID錛?br>銆銆
銆銆jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "(I)V");
銆銆
銆銆浣跨敤GetMethdoID鏂規硶鑾峰彇浣犺浣跨敤鐨勬柟娉曠殑MethdoID銆傚叾鍙傛暟鐨勬剰涔夛細
銆銆
銆銆env??>JNIEnv
銆銆
銆銆cls??>絎竴姝ヨ幏鍙栫殑jclass
銆銆
銆銆"callback"??>瑕佽皟鐢ㄧ殑鏂規硶鍚?br>銆銆
銆銆"(I)V"??>鏂規硶鐨凷ignature
銆銆
銆銆鈶?璋冪敤鏂規硶錛?br>銆銆
銆銆(*env)->CallVoidMethod(env, obj, mid, depth);
銆銆
銆銆浣跨敤CallVoidMethod鏂規硶璋冪敤鏂規硶銆傚弬鏁扮殑鎰忎箟錛?br>銆銆
銆銆env??>JNIEnv
銆銆
銆銆obj??>閫氳繃鏈湴鏂規硶絀胯繃鏉ョ殑jobject
銆銆
銆銆mid??>瑕佽皟鐢ㄧ殑MethodID錛堝嵆絎簩姝ヨ幏寰楃殑MethodID錛?br>銆銆
銆銆depth??>鏂規硶闇瑕佺殑鍙傛暟錛堝搴旀柟娉曠殑闇姹傦紝娣誨姞鐩稿簲鐨勫弬鏁幫級 bitsCN.nET涓浗緗戠鍗氬
銆銆
銆銆娉細榪欓噷浣跨敤鐨勬槸CallVoidMethod鏂規硶璋冪敤錛屽洜涓烘病鏈夎繑鍥炲鹼紝濡傛灉鏈夎繑鍥炲肩殑璇濅嬌鐢ㄥ搴旂殑鏂規硶錛屽湪鍚庨潰浼氭彁鍒般?br>銆銆
銆銆鏂規硶鐨凷ignature
銆銆
銆銆鏂規硶鐨凷ignature鏄敱鏂規硶鐨勫弬鏁板拰榪斿洖鍊肩殑綾誨瀷鍏卞悓鏋勬垚鐨勶紝涓嬮潰鏄粬浠殑緇撴瀯錛?br>銆銆
銆銆"(argument-types)return-type"
銆銆
銆銆鍏朵腑Java紼嬪簭涓弬鏁扮被鍨嬪拰鍏跺搴旂殑鍊煎涓嬶細
銆銆
銆銆Signature銆銆Java涓殑綾誨瀷
銆銆Z銆銆銆銆銆銆銆boolean
銆銆B銆銆銆銆銆銆銆byte
銆銆C銆銆銆銆銆銆銆char
銆銆S銆銆銆銆銆銆銆short
銆銆I銆銆銆銆銆銆銆int
銆銆J銆銆銆銆銆銆銆long
銆銆F銆銆銆銆銆銆銆float
銆銆D銆銆銆銆銆銆銆double
銆銆L fully-qualified-class;銆銆 fully-qualified-class
銆銆
銆銆[ type銆銆type[]
銆銆
銆銆( arg-types ) ret-type銆銆method type
銆銆
銆銆涓涓狫ava綾葷殑鏂規硶鐨凷ignature鍙互閫氳繃javap鍛戒護鑾峰彇錛?br>銆銆
銆銆javap -s -p Java綾誨悕
銆銆
銆銆緇欒皟鐢ㄧ殑鍑芥暟浼犲弬鏁幫細
銆銆
銆銆閫氬父鎴戜滑鐩存帴鍦╩ethodID鍚庨潰灝嗚浼犵殑鍙傛暟娣誨姞鍦ㄥ悗闈紝浣嗘槸榪樻湁鍏朵粬鐨勬柟娉曚篃鍙互浼犲弬鏁幫細
銆銆
銆銆CallVoidMethodV鍙互鑾峰彇涓涓暟閲忓彲鍙樼殑鍒楄〃浣滀負鍙傛暟錛?www_bitscn_com
銆銆
銆銆CallVoidMethodA鍙互鑾峰彇涓涓猽nion銆?br>銆銆
銆銆璋冪敤闈欐佹柟娉曪細
銆銆
銆銆灝辨槸灝嗙浜屾鍜岀涓夋璋冪敤鐨勬柟娉曟敼涓哄搴旂殑錛?br>銆銆
銆銆GetStaticMethodID鑾峰彇瀵瑰簲鐨勯潤鎬佹柟娉曠殑ID
銆銆
銆銆CallStaticIntMethod璋冪敤闈欐佹柟娉?br>銆銆
銆銆璋冪敤瓚呯被鐨勬柟娉曪細
銆銆
銆銆鐢ㄧ殑姣旇緝灝戯紝鑷繁鐪嬪暒銆俕_^銆?br>銆銆
銆銆4)璁塊棶Java瀵硅薄鐨勫睘鎬э細
銆銆
銆銆璁塊棶Java瀵硅薄鐨勫睘鎬у拰璁塊棶Java瀵硅薄鐨勬柟娉曞熀鏈笂涓鏍鳳紝鍙渶瑕佸皢鍑芥暟閲岄潰鐨凪ethod鏀逛負Field鍗沖彲
]]>
do
CLASSPATH="$CLASSPATH:""$jar"
done
windows :
SETLOCAL ENABLEDELAYEDEXPANSION
set LIB=xx
set CLASSPATH=.
FOR %%C IN (LIB\*.jar) DO set CLASSPATH=!CLASSPATH!;%%C
echo %CLASSPATH%
unix ksh:
鏆傛棤
]]>
聽
1.4.2jdk緙栬瘧鎵ц銆傞暱鏃墮棿鎵ц娌℃湁鍙戠幇鏈夌綉涓婃墍璇寸殑鐢變簬jit浼樺寲瀵艱嚧鐨勫綋鍒嗛厤瀹孎oo鐨勫唴瀛橈紝Foo鏋勯犲嚱鏁版湭鍒濆鍖栧畬鎴愬氨灝嗗叾鍦板潃璧嬪肩粰foo鐨勯敊璇傜浉淇¤繖鏃跺檍it宸茬粡瀵逛唬鐮佽繘琛屼簡浼樺寲銆?br />
鍥藉緗戝潃鍏充簬Double-Checked Locking鐨勬枃绔?a >http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
Paul Jakubik found an example of a use of double-checked locking that did not work correctly. A slightly cleaned up version of that code is available here.
When run on a system using the Symantec JIT, it doesn't work. In particular, the Symantec JIT compiles
singletons[i].reference = new Singleton();
to the following (note that the Symantec JIT using a handle-based object allocation system).
0206106A mov eax,0F97E78h 0206106F call 01F6B210 ; allocate space for ; Singleton, return result in eax 02061074 mov dword ptr [ebp],eax ; EBP is &singletons[i].reference ; store the unconstructed object here. 02061077 mov ecx,dword ptr [eax] ; dereference the handle to ; get the raw pointer 02061079 mov dword ptr [ecx],100h ; Next 4 lines are 0206107F mov dword ptr [ecx+4],200h ; Singleton's inlined constructor 02061086 mov dword ptr [ecx+8],400h 0206108D mov dword ptr [ecx+0Ch],0F84030h
As you can see, the assignment to singletons[i].reference is performed before the constructor for Singleton is called. This is completely legal under the existing Java memory model, and also legal in C and C++ (since neither of them have a memory model).
涓婇潰鏄浗澶栫綉绔欑粰鍑虹殑jit浠g爜鍜岃鏄庛?br />
import org.apache.bcel.Constants;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.InstructionConstants;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.ObjectType;
import org.apache.bcel.generic.PUSH;
import org.apache.bcel.generic.Type;
public class BCELTiming {
聽聽聽 /**
聽聽聽聽 * Add timing wrapper to method of class. The method can accept any
聽聽聽聽 * arguments and return any type (including void), but must be a normal
聽聽聽聽 * (non-static, non-initializer) method to be used with this code as
聽聽聽聽 * currently implemented. Handling the other types of methods would not
聽聽聽聽 * involve any fundamental changes to the code.
聽聽聽聽 *
聽聽聽聽 * @param cgen
聽聽聽聽 *聽聽聽聽聽聽聽聽聽聽聽 generator for class being modified
聽聽聽聽 * @param method
聽聽聽聽 *聽聽聽聽聽聽聽聽聽聽聽 current method to be enhanced with timing wrapper
聽聽聽聽 */
聽聽聽 private static void addWrapper(ClassGen cgen, Method method) {
聽聽聽聽聽聽聽 // set up the construction tools
聽聽聽聽聽聽聽 InstructionFactory ifact = new InstructionFactory(cgen);
聽聽聽聽聽聽聽 InstructionList ilist = new InstructionList();
聽聽聽聽聽聽聽 ConstantPoolGen pgen = cgen.getConstantPool();
聽聽聽聽聽聽聽 String cname = cgen.getClassName();
聽聽聽聽聽聽聽 MethodGen wrapgen = new MethodGen(method, cname, pgen);
聽聽聽聽聽聽聽 wrapgen.setInstructionList(ilist);
聽聽聽聽聽聽聽 // rename a copy of the original method
聽聽聽聽聽聽聽 MethodGen methgen = new MethodGen(method, cname, pgen);
聽聽聽聽聽聽聽 cgen.removeMethod(method);
聽聽聽聽聽聽聽 String iname = methgen.getName() + "$impl";
聽聽聽聽聽聽聽 methgen.setName(iname);
聽聽聽聽聽聽聽 cgen.addMethod(methgen.getMethod());
聽聽聽聽聽聽聽 //浠ヤ笂鏄竴涓嬪垵濮嬪寲鐨勫伐浣?br />聽聽聽聽聽聽聽
聽聽聽聽聽聽聽 // compute the size of the calling parameters
聽聽聽聽聽聽聽 // operand stack鎿嶄綔鏁板爢鏍?br />聽聽聽聽聽聽聽 Type[] types = methgen.getArgumentTypes(); // 鍙栧嚭鍙傛暟綾誨瀷鏁扮粍
聽聽聽聽聽聽聽 // solt浠h〃鏈湴鍙橀噺鐨勫爢鏍堝亸縐婚噺,閲屽ご鍌ㄥ瓨浜嗚皟鐢╩ethen浠h〃鐨勫嚱鏁扮殑鍙傛暟
聽聽聽聽聽聽聽 int slot = methgen.isStatic() ? 0 : 1; // 榪欑鏂瑰紡涓嶫ava濡備綍澶勭悊鏂規硶璋冪敤鏈夊叧銆傚浜庨潪闈欐佺殑鏂規硶錛屾瘡嬈¤皟鐢ㄧ殑絎竴涓紙闅愯棌鐨勶級鍙傛暟鏄洰鏍囧璞$殑this寮曠敤錛堝氨鏄綅緗?鍌ㄥ瓨鐨勫唴瀹癸級銆?br />聽聽聽聽聽聽聽 for (int i = 0; i < types.length; i++) {
聽聽聽聽聽聽聽聽聽聽聽 slot += types[i].getSize();// 绱涓釜鍙傛暟綾誨瀷鐨勯暱搴︼紝
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 // 鐜板湪solt鎸囧悜鏈鍚庝竴涓弬鏁扮殑涓嬩竴涓綅緗?/p>
聽聽聽聽聽聽聽 // save time prior to invocation
聽聽聽聽聽聽聽 // 璋冪敤闈欐佺殑long java.lang.System.currentTimeMillis()鏂規硶,璋冪敤緇撴潫鍚庡嚱鏁扮殑榪斿洖鐨刲ong綾誨瀷鐨勫間細鍘嬪叆operand stack鎿嶄綔鏁板爢鏍?br />聽聽聽聽聽聽聽 ilist.append(ifact.createInvoke("java.lang.System",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 "currentTimeMillis", Type.LONG, Type.NO_ARGS,
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 Constants.INVOKESTATIC));
聽聽聽聽聽聽聽 ilist.append(InstructionFactory.createStore(Type.LONG, slot));// 灝唎perand stack鐨則op淇濆瓨鍒版湰鍦板彉閲忓爢鏍堢殑slot浣嶇疆,operand stack寮瑰嚭long鍊?/p>
聽聽聽聽聽聽聽 // call the wrapped method
聽聽聽聽聽聽聽 int offset = 0; // 鍋忕Щ閲?br />聽聽聽聽聽聽聽 short invoke = Constants.INVOKESTATIC; // 棰勫厛璁劇疆涓鴻皟鐢ㄩ潤鎬佸嚱鏁?br />聽聽聽聽聽聽聽 if (!methgen.isStatic()) { // 濡傛灉涓嶆槸璋冪敤闈欐佸嚱鏁?灝嗚皟鐢ㄧ殑絎竴涓紙闅愯棌鐨勶級鍙傛暟(鐩爣瀵硅薄鐨則his寮曠敤)鍘嬪叆operand stack
聽聽聽聽聽聽聽聽聽聽聽 ilist.append(InstructionFactory.createLoad(Type.OBJECT, 0));
聽聽聽聽聽聽聽聽聽聽聽 offset = 1;// 鍋忕Щ閲忓姞1
聽聽聽聽聽聽聽聽聽聽聽 invoke = Constants.INVOKEVIRTUAL;// 璁劇疆涓鴻皟鐢ㄩ潪闈欐佸嚱鏁?br />聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 for (int i = 0; i < types.length; i++) { // 閬嶅巻鎵鏈夊弬鏁?br />聽聽聽聽聽聽聽聽聽聽聽 Type type = types[i];
聽聽聽聽聽聽聽聽聽聽聽 ilist.append(InstructionFactory.createLoad(type, offset)); // 鎸夊弬鏁扮被鍨嬫妸鍙傛暟涓涓釜浠庢湰鍦板彉閲忓爢鏍堝彇鍑猴紝鍘嬪叆operand stack
聽聽聽聽聽聽聽聽聽聽聽 offset += type.getSize();
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 Type result = methgen.getReturnType();// 鍙栧緱瑕佽皟鐢ㄥ嚱鏁扮殑榪斿洖鍊肩被鍨?br />聽聽聽聽聽聽聽 ilist.append(ifact.createInvoke(cname, iname, result, types, invoke));// 璋冪敤鏂規硶鍚嶄負iname鐨勫嚱鏁?/p>
聽聽聽聽聽聽聽 // store result for return later
聽聽聽聽聽聽聽 if (result != Type.VOID) {
聽聽聽聽聽聽聽聽聽聽聽 ilist.append(InstructionFactory.createStore(result, slot + 2)); // 灝嗗悕涓篿name鐨勫嚱鏁拌繑鍥炲煎鍒跺埌鏈湴鍙橀噺鍫嗘爤鐨剆lot+2鐨勪綅緗笂
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 // print time required for method call
聽聽聽聽聽聽聽 // 鑾峰彇闈欐佸璞ava.lang.System.out鐨勫紩鐢?榪斿洖鍊煎帇鍏perand stack
聽聽聽聽聽聽聽 ilist.append(ifact.createFieldAccess("java.lang.System", "out",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 new ObjectType("java.io.PrintStream"), Constants.GETSTATIC));
聽聽聽聽聽聽聽 ilist.append(InstructionConstants.DUP);// 鍙杘perand stack鐨則op,鍘嬪叆operand stack銆傚畬鎴愬悗load_stack鐨勫ご涓や釜鍏冪礌鏄潤鎬佸璞ava.lang.System.out鐨勫紩鐢?br />聽聽聽聽聽聽聽 ilist.append(InstructionConstants.DUP);// 鍙杘perand stack鐨則op,鍘嬪叆operand stack銆傜幇鍦ㄦ湁3涓猨ava.lang.System.out鐨勫紩鐢ㄣ備緵涓嬮潰3嬈¤皟鐢╫ut.print()鍑芥暟浣跨敤
聽聽聽聽聽聽聽 String text = "Call to method " + methgen.getName() + " took ";
聽聽聽聽聽聽聽 ilist.append(new PUSH(pgen, text));// 灝唗ext鏀懼叆pgen錛堜唬琛ㄥ父閲忔睜錛?騫舵妸鍏跺湪pgen鐨勫紩鐢ㄥ帇鍏perand stack(渚沷ut.print(Sting)璋冪敤鐨勫弬鏁?
聽聽聽聽聽聽聽 ilist.append(ifact.createInvoke("java.io.PrintStream", "print",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 Type.VOID, new Type[] { Type.STRING },
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 Constants.INVOKEVIRTUAL));// 璋冪敤緇撴潫錛宱perand stack寮瑰嚭涓涓猄tring鐨勫紩鐢ㄥ拰涓涓猳ut鐨勫紩鐢?榪樺墿2涓猳ut),鍑芥暟娌℃湁榪斿洖鍊?/p>
聽聽聽聽聽聽聽 ilist.append(ifact.createInvoke("java.lang.System",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 "currentTimeMillis", Type.LONG, Type.NO_ARGS,
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 Constants.INVOKESTATIC));// 璋冪敤java.lang.System.currentTimeMillis()鏂規硶,璋冪敤緇撴潫鍚庡嚱鏁扮殑榪斿洖鐨刲ong綾誨瀷鐨勫間細鍘嬪叆鍫嗘爤operand stack
聽聽聽聽聽聽聽 ilist.append(InstructionFactory.createLoad(Type.LONG, slot));// 浠庢湰鍦板彉閲忓爢鏍堢殑slot浣嶇疆杞藉叆鍏堝墠鍌ㄥ瓨鐨刲ong鍊鹼紝鍘嬪叆operand stack
聽聽聽聽聽聽聽 ilist.append(InstructionConstants.LSUB);// 璋冪敤long鐨勫噺娉曟寚浠?寮瑰嚭2涓猯ong鍊鹼紝騫舵妸緇撴灉鍘嬪叆operand stack,鐜板湪operand stack鐨則op絎竴涓槸long錛岀浜屼釜鏄痮ut鐨勫紩鐢?br />聽聽聽聽聽聽聽 ilist.append(ifact.createInvoke("java.io.PrintStream", "print",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 Type.VOID, new Type[] { Type.LONG }, Constants.INVOKEVIRTUAL));// 璋冪敤out.print(long)鏂規硶
聽聽聽聽聽聽聽 ilist.append(new PUSH(pgen, " ms."));// 灝哠tring瀵硅薄" ms."鏀懼叆pgen,騫舵妸鍏跺湪pgen鐨勫紩鐢ㄥ帇鍏perand stack(渚沷ut.print(Sting)璋冪敤鐨勫弬鏁?
聽聽聽聽聽聽聽 ilist
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 .append(ifact.createInvoke("java.io.PrintStream", "println",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 Type.VOID, new Type[] { Type.STRING },
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 Constants.INVOKEVIRTUAL));
聽聽聽聽聽聽聽 // return result from wrapped method call
聽聽聽聽聽聽聽 if (result != Type.VOID) {
聽聽聽聽聽聽聽聽聽聽聽 ilist.append(InstructionFactory.createLoad(result, slot + 2));// 澶勭悊榪斿洖鍊?濡傛灉涓嶄負絀猴紝浠庢湰鍦板璞″爢鏍堢殑slot+2浣嶇疆璇誨彇鎸囧畾綾誨瀷鐨勮繑鍥炲煎帇鍏perand stack
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 ilist.append(InstructionFactory.createReturn(result)); //璋冪敤澶勭悊榪斿洖鍊肩殑鎸囦護錛宺esult涓鴻繑鍥炲肩殑綾誨瀷
聽聽聽聽聽聽聽 //涓嬮潰鏄竴涓嬫壂灝懼伐浣?br />聽聽聽聽聽聽聽 // finalize the constructed method
聽聽聽聽聽聽聽 wrapgen.stripAttributes(true);
聽聽聽聽聽聽聽 wrapgen.setMaxStack();
聽聽聽聽聽聽聽 wrapgen.setMaxLocals();
聽聽聽聽聽聽聽 cgen.addMethod(wrapgen.getMethod());
聽聽聽聽聽聽聽 ilist.dispose();
聽聽聽 }
聽聽聽 public static void main(String[] argv) {
聽聽聽聽聽聽聽 if (argv.length == 2 && argv[0].endsWith(".class")) {
聽聽聽聽聽聽聽聽聽聽聽 try {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 JavaClass jclas = new ClassParser(argv[0]).parse();
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 ClassGen cgen = new ClassGen(jclas);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 Method[] methods = jclas.getMethods();
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 int index;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 for (index = 0; index < methods.length; index++) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (methods[index].getName().equals(argv[1])) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 break;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (index < methods.length) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 addWrapper(cgen, methods[index]);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 FileOutputStream fos = new FileOutputStream(argv[0]);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 cgen.getJavaClass().dump(fos);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 fos.close();
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 } else {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 System.err.println("Method " + argv[1] + " not found in "
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 + argv[0]);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽 } catch (IOException ex) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 ex.printStackTrace(System.err);
聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 } else {
聽聽聽聽聽聽聽聽聽聽聽 System.out.println("Usage: BCELTiming class-file method-name");
聽聽聽聽聽聽聽 }
聽聽聽 }
}
鐩稿javassist錛宐cel紜疄姣旇緝澶嶆潅銆備絾鏄痓cel緇欐垜鐨勬劅瑙夋瘮杈冭嚜鐢憋紝鏈夌涓鍒囧敖鍦ㄦ帉鎻$殑鎰熻錛岃繖涓鐐規瘮杈冩垜鍠滄銆?br />铏界劧鑷敱錛屼絾鏄敤bcel鍐欎竴涓被鐨勫疄鐜扮粷瀵逛笉浼氭槸涓浠惰浜哄紑蹇冪殑浜嬫儏錛屽鏋滅宸т綘鐨勫疄鐜板張紼嶅井澶嶆潅浜嗙偣(姣斿瀹炵幇浜唜x鎺ュ彛錛屽張澧炲姞浜嗕竴浜涘嚱鏁板拰鎴愬憳鍙橀噺)銆傝屼笖浣犵殑瀹炵幇鏈繀浼氭瘮javac緙栬瘧鍑烘潵鐨勪唬鐮佹晥鐜囬珮錛堜笉鑰冭檻jvm鐨勫姩鎬佷紭鍖栵級銆?br />涓嶈繃錛屽厛鎶婁綘瑕佸疄鐜扮殑綾葷殑浠g爜鍐欏嚭鏉ワ紝鎸夌収浠g爜鏉ュ啓bcel鐨勫疄鐜幫紝浼氶檷浣庝簺瀹炵幇闅懼害銆?/p>