• 沒有找到結果。

原生方法的機制(N ATIVE METHOD )說明

第四章 系統軟體介紹

4.4. ISR介紹

4.4.3. 原生方法的機制(N ATIVE METHOD )說明

因為原生方法的呼叫在 bytecode 層級來看是與一般呼叫方法是相同的,透過 invokevirtual、

invokestatic 指令後面接的常數索引區段索引值,一樣以間接的方式最後取到參照資料在記憶 體中的位置,並抓取參照資料,而我們實作原生方法的機制是透過在物件型別解析時,檢察 所屬其物件型別的方法是否為原生方法,如果是的話,我們則會在參照資料裡上放入屬於原 生方法格式的資料,格式如圖 40,我們會犧牲 0xFF 開頭的 Class ID 用以表示此參照資料為

Before Process After

: : Class ID | 0x0000

: Class ID | Offset

: : hos_a rg1

hos_a rg3 hos_a rg4 hos_a rg2

Reference data

hos_a rg5

我們在 ISR 的 ID 上會用前 16bit 以 0 或 1 區分是否會為 Native method 所觸發,當 JAIP 發出中斷時,我們會先確認其是否為 Native method 所觸發的,之後跳去執行我們建立的 native method table 上對應到的 function,機制如 0 所示,其執行 Native method 實的系統變化如 0 所示。

圖41. Native method 機制

圖42. Invoke native method 執行時的狀態變化

Native method table 0 Function ptr

1 :

: :

ISR ID

Definition Native flag ID

Space(bit) 16 16 Native method code

void method(){

: implementation ;

: }

ind ex

Parameter N-3 : Parameter 1

stack

Before After

Parameter N-3 : Parameter 1

:

process

host_arg

hos_a rg5 :

hos_a rg1

Parameter N : Parameter N-2

: : Return value TOS_A

TOS_B TOS_C

:

而為了配合電路在 native method 的結束時對 stack 的整理操作方便,我們在傳遞不同個 數的參數時,擺放在 register file 上的順序也不同,擺放順序如表 3 所示,而目前實作的原生 方法如表 4 所列。

表 3 傳遞不同參數個數時,參數位在 register file 上的位置,最多支援 8 個參數

Parameter order

Parameter count 1 2 3 4 5 6 7 8

TOS_A ○345678

TOS_B ○2234567

TOS_C ○11123456

Host_Arg 5 ○5

Host_Arg 4 ○44

Host_Arg 3 ○333

Host_Arg 2 ○2222

Host_Arg 1 ○11111

表 4 目前對 System Class 所支援的原生方法

Java_java_lang_Object_getClass Java_java_lang_Class_forName Java_java_lang_Class_newInstance Java_java_lang_Thread_yield Java_java_lang_System_arraycopy

Java_java_lang_System_currentTimeMillis

實作原生方法的依據主要參考自 KVM 當中實作的原生方法的邏輯,並撰寫符合我們平 台的版本,接下來會說明各原生方法的實作內容。

java/lang/Object/getClass

因為在我們配置一個新產生的物件時,其在記憶體中最前面 32bit 的資料就是存放此物件所 屬的 Class ID,所以當我們今天取得 Object reference 時,我們即可以透過這個位址讀取 Class ID,並回傳給 JAIP。

java/lang/Class/forName

透過取得的 String Object 參數,我們取出其字串的 field data,並以此為要解析的物件型別名 稱呼叫物件型別解析器,最後再回傳一個 Class Object 給 JAIP,但是其所屬的 Class ID 我們 會填入此次解析物件型別的 Class ID,而非 Class 這個物件型別的 Class ID。

java/lang/Class/newInstance

透過傳遞出的由 Class 造出的 Object,我們取出其存放的 Class ID,再透過此 Class ID 去配置 一個新物件記憶體空間,並回傳 object reference 給 JAIP。

java/lang/Thread/yield

目前平台尚未提供多執行緒的功能,但此方法會去確認目前系統中的執行緒個數,當個數大 於一時,我們會去設定切換執行緒的訊號,之後可以延伸做為觸發電路做切換執行緒的機制。

java/lang/System/currentTimeMillis

這邊我是透過讀取 JAIP 內部的 timer 暫存器的值,再去對系統頻率換算得到 JAIP 啟動之後 的毫秒數,再將這個時間資訊傳回給 JAIP。

java/lang/System/arraycopy

arraycopy 會使用到五個參數,其中兩個分別代表陣列的記憶體位址、另外兩個表示從陣列上 要開始複製及貼上的起始位置,最後一個表示要複製資料的長度,在這部分實作兩個遞迴呼

叫的函式 copy_obj 及 copy_array 來實作,這兩個函式的流程如圖 43、圖 44 所示,當呼叫 arraycopy 時會根據 array tag 去決定呼叫 copy_obj、copy_array 或是直接複製內容,也因為實 作這個原生方法,所以我們對陣列及 field data 都做了額外的 tag 表示其中的意義,來幫助我 們在複製物件及陣列時,使用正確的複製的方式。

圖43. copy_array(ref)流程

Check all elements are finished Check all elements

are finished Check element is

array type Yes

Check element is object type

Call copy_obj(ref)

Yes No

Call copy_array(ref) Copy primitive data

Get array t ag

No

No No

Yes Yes

圖44. copy_obj(ref)流程

java/lang/System/getProperty0

透過取得的 String Object 參數,取出其字串內容的資訊,這邊參考自 KVM 中實作的方式會 再呼叫 getSystemProperty 的函式,取得表示系統資訊的字串,並以此字串產生一個 String Object 回傳給 JAIP。

java/lang/String/charAt

在 String 的 field data 中,其中一項是用來描述另一個 field data 字元陣列的有效起始位置,當 我們得到 String Object 參數時,會在其字元陣列中,將其起始位移量加上索引值得字元回傳 給 JAIP。

Check all field d ata is finished

Get field tag

Check field data is

array type

Yes

Check field data is object type

Copy field data

Yes

No

Call copy_array(ref)

Yes No

Call copy_obj(ref)

No

java/lang/String/equals

比對兩個 String Object 在字元陣列的起始位置之後的內容是否相同,並將結果回傳給 JAIP。

java/lang/String/indexOf__I

在 String Object 上的 field data 中,從字元陣列的起始位置開始搜尋指定字元出現的索引值,

並回傳給 JAIP。

java/lang/String/indexOf__II

在 String Object 上的 field data 中,從字元陣列的起始位置加上一個指定搜尋的位移量,開始 搜尋指定字元出現的索引值,並回傳給 JAIP。

java/lang/StringBuffer/append__I

產生新的字元陣列,並將數值轉成字元附加在原來在 String Object 的字元陣列之後,再存回 原 String Object 的 field data 中。

java/lang/StringBuffer/append__Ljava_lang_String_2

將欲附加的 String Object 的字元陣列附加在原來在 String Object 的字元陣列之後,再存回原 String Object 的 field data 中。

java/lang/StringBuffer/toString

透過取得的 StringBuffer Object 參數,修改其所屬Class ID 並對其 field data 的順序做調整,

修改成符合 String 的格式。

相關文件