程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> J2ME >> KVM的類加載

KVM的類加載

編輯:J2ME

首先簡要介紹一下class文件的結構(詳細內容請參考Java虛擬機規范,在《深入Java虛擬機》一書中也有詳細描述):

長度(字節)

名稱

解釋

4

magic

0xCAFEBABEJava文件的標識,常稱為“魔數”

2

minor_version

次版本號

2

major_version

主版本號

2

constant_pool_count

常量池中項目個數

(constant_pool_count-1)*cp_item

constant_pool

常量池,其中存放了(constant_pool_count-1)個常量池項

2

Access_flags

class的類型信息

2

this_class

class的全限定名的常量池項索引

2

super_class

超類的全限定名的常量池項索引

2

interfaces_count

實現/擴展的接口數

2*interfaces_count

interfaces

實現/擴展的接口名的常量池項索引

2

fIElds_count

字段數

fIElds_count* cp_item

fIElds

字段信息表

2

methods_count

方法數

methods_count* cp_item

methods

方法信息表

2

attributes_count

屬性數

attributes_count* cp_item

attributes

屬性信息表

文件系統中的一個class文件,要想成為能在虛擬上運行的Java程序的一部分,必須經過裝載->連接->初始化三個步驟。其中裝載是最基礎的一步,它的作用是讀取class文件的信息,並生成對象。下面介紹一下KVM中與類加載相關的內容是如何實現的。

 

數據結構:

在頭文件kvm/vmcommon/h/class.h中定義有兩個非常重要的結構體:

/* CLASS */
struct classStruct {
    COMMON_OBJECT_INFO(INSTANCE_CLASS)
    UString packageName;            /* Everything before the final '/' */
    UString baseName;               /* Everything after the final '/' */
    CLASS   next;                   /* Next item in this hash table bucket */
    unsigned short AccessFlags;     /* Access information */
    unsigned short key;             /* Class key */
};
typedef struct classStruct*         CLASS;

/* INSTANCE_CLASS */
struct instanceClassStruct {
    struct classStruct clazz;       /* common info */
    /* And specific to instance classes */
    INSTANCE_CLASS superClass;      /* Superclass, unless Java.lang.Object */
    CONSTANTPOOL constPool;         /* Pointer to constant pool */
    FIELDTABLE  fIEldTable;         /* Pointer to instance variable table */
    METHODTABLE methodTable;        /* Pointer to virtual method table */
    unsigned short* ifaceTable;     /* Pointer to interface table */
    POINTERLIST staticFIElds;       /* Holds static fIElds of the class */
    short   instSize;               /* The size of class instances */
    short status;                   /* Class readiness status */
    THREAD initThread;              /* Thread performing class initialization */
    NativeFuncPtr finalizer;        /* Pointer to finalizer */
};
typedef struct instanceClassStruct* INSTANCE_CLASS;

classStructinstanceClassStruct這兩個結構體都是與class(可能包括類和接口)有關的,但不所不同。classStruct所提供是一些“外圍信息”,包括全限定名和可見性等,是一個class區分其它class的基本信息;instanceClassStruct所提供的是一些“內容信息”,是一個類本身所定義的內容,比如方法表、字段表等等。

 

程序實現:

下面來看一看在KVMinstanceClassStruct的信息是如何讀取的。

一個kvm虛擬機在運行時,class來自於兩種來源:一是系統類庫,這些類來自KVM本身;二是用戶程序,來自文件系統。下面分別介紹:

1、前文提到過,對於系統類庫,KVM會先把class文件轉化為C語言源代碼,然後編入kvm可執行程序中,這樣當使用系統類庫時,kvm就不再訪問外部,這一步驟叫可暫稱為ROMROM過程中所做的事情之一就是生成所有系統類庫中classINSTANCE_CLASS,也就是說,這些類的信息早在ROM的過程中就已准備好,使用時只要讀入即可。

ROM生成的INSTANCE_CLASS信息存放在源文件tools/jcc/ROMJavaUnix.cstatic struct AllClassblocks_Struct AllClassblocks結構中,使用這一結構的代碼也在同一文件中,比如:

 

INSTANCE_CLASS JavaLangString =
     (INSTANCE_CLASS)&AllClassblocks.Java_lang_String;

這裡就生成了String類對應的INSTANCE_CLASS結構。

2、對於用戶定義的類,INSTANCE_CLASS信息就要從文件系統中獲得。

獲得類信息的主要入口函數是

void loadClassfile(INSTANCE_CLASS InitiatingClass, bool_t fatalErrorIfFail);

在文件kvm/vmcommon/src/loader.c中。其中參數InitiatingClass就是一個空的INSTANCE_CLASS結構體,在loadClassfile函數中,InitiatingClass的內容將被逐步填充。

loadClassfile中,將調用另一個重要的函數:

static void loadRawClass(INSTANCE_CLASS CurrentClass, bool_t fatalErrorIfFail);

在這個函數中,將調用下列各方法分別載入class文件中的各種信息:

函數名(參數及返回值省略)

功能

loadVersionInfo()

載入版本號

loadConstantPool()

載入常量池

loadClassInfo()

載入類型信息

loadInterfaces()

載入所實現的接口

loadFIElds()

載入字段表

loadMethods()

載入方法表

ignoreAttributes()

載入擴展的屬性表

上表中的每一個函數都會帶有一個FILEPOINTER_HANDLE型的參數,它是一個文件的句柄,這些函數就是從這個文件中順序讀取各種信息並存入INSTANCE_CLASS結構中的。

首先簡要介紹一下class文件的結構(詳細內容請參考Java虛擬機規范,在《深入Java虛擬機》一書中也有詳細描述):

長度(字節)

名稱

解釋

4

magic

0xCAFEBABEJava文件的標識,常稱為“魔數”

2

minor_version

次版本號

2

major_version

主版本號

2

constant_pool_count

常量池中項目個數

(constant_pool_count-1)*cp_item

constant_pool

常量池,其中存放了(constant_pool_count-1)個常量池項

2

Access_flags

class的類型信息

2

this_class

class的全限定名的常量池項索引

2

super_class

超類的全限定名的常量池項索引

2

interfaces_count

實現/擴展的接口數

2*interfaces_count

interfaces

實現/擴展的接口名的常量池項索引

2

fIElds_count

字段數

fIElds_count* cp_item

fIElds

字段信息表

2

methods_count

方法數

methods_count* cp_item

methods

方法信息表

2

attributes_count

屬性數

attributes_count* cp_item

attributes

屬性信息表

文件系統中的一個class文件,要想成為能在虛擬上運行的Java程序的一部分,必須經過裝載->連接->初始化三個步驟。其中裝載是最基礎的一步,它的作用是讀取class文件的信息,並生成對象。下面介紹一下KVM中與類加載相關的內容是如何實現的。

 

數據結構:

在頭文件kvm/vmcommon/h/class.h中定義有兩個非常重要的結構體:

/* CLASS */
struct classStruct {
    COMMON_OBJECT_INFO(INSTANCE_CLASS)
    UString packageName;            /* Everything before the final '/' */
    UString baseName;               /* Everything after the final '/' */
    CLASS   next;                   /* Next item in this hash table bucket */
    unsigned short AccessFlags;     /* Access information */
    unsigned short key;             /* Class key */
};
typedef struct classStruct*         CLASS;

/* INSTANCE_CLASS */
struct instanceClassStruct {
    struct classStruct clazz;       /* common info */
    /* And specific to instance classes */
    INSTANCE_CLASS superClass;      /* Superclass, unless Java.lang.Object */
    CONSTANTPOOL constPool;         /* Pointer to constant pool */
    FIELDTABLE  fIEldTable;         /* Pointer to instance variable table */
    METHODTABLE methodTable;        /* Pointer to virtual method table */
    unsigned short* ifaceTable;     /* Pointer to interface table */
    POINTERLIST staticFIElds;       /* Holds static fIElds of the class */
    short   instSize;               /* The size of class instances */
    short status;                   /* Class readiness status */
    THREAD initThread;              /* Thread performing class initialization */
    NativeFuncPtr finalizer;        /* Pointer to finalizer */
};
typedef struct instanceClassStruct* INSTANCE_CLASS;

classStructinstanceClassStruct這兩個結構體都是與class(可能包括類和接口)有關的,但不所不同。classStruct所提供是一些“外圍信息”,包括全限定名和可見性等,是一個class區分其它class的基本信息;instanceClassStruct所提供的是一些“內容信息”,是一個類本身所定義的內容,比如方法表、字段表等等。

 

程序實現:

下面來看一看在KVMinstanceClassStruct的信息是如何讀取的。

一個kvm虛擬機在運行時,class來自於兩種來源:一是系統類庫,這些類來自KVM本身;二是用戶程序,來自文件系統。下面分別介紹:

1、前文提到過,對於系統類庫,KVM會先把class文件轉化為C語言源代碼,然後編入kvm可執行程序中,這樣當使用系統類庫時,kvm就不再訪問外部,這一步驟叫可暫稱為ROMROM過程中所做的事情之一就是生成所有系統類庫中classINSTANCE_CLASS,也就是說,這些類的信息早在ROM的過程中就已准備好,使用時只要讀入即可。

ROM生成的INSTANCE_CLASS信息存放在源文件tools/jcc/ROMJavaUnix.cstatic struct AllClassblocks_Struct AllClassblocks結構中,使用這一結構的代碼也在同一文件中,比如:

 

INSTANCE_CLASS JavaLangString =
     (INSTANCE_CLASS)&AllClassblocks.Java_lang_String;

這裡就生成了String類對應的INSTANCE_CLASS結構。

2、對於用戶定義的類,INSTANCE_CLASS信息就要從文件系統中獲得。

獲得類信息的主要入口函數是

void loadClassfile(INSTANCE_CLASS InitiatingClass, bool_t fatalErrorIfFail);

在文件kvm/vmcommon/src/loader.c中。其中參數InitiatingClass就是一個空的INSTANCE_CLASS結構體,在loadClassfile函數中,InitiatingClass的內容將被逐步填充。

loadClassfile中,將調用另一個重要的函數:

static void loadRawClass(INSTANCE_CLASS CurrentClass, bool_t fatalErrorIfFail);

在這個函數中,將調用下列各方法分別載入class文件中的各種信息:

函數名(參數及返回值省略)

功能

loadVersionInfo()

載入版本號

loadConstantPool()

載入常量池

loadClassInfo()

載入類型信息

loadInterfaces()

載入所實現的接口

loadFIElds()

載入字段表

loadMethods()

載入方法表

ignoreAttributes()

載入擴展的屬性表

上表中的每一個函數都會帶有一個FILEPOINTER_HANDLE型的參數,它是一個文件的句柄,這些函數就是從這個文件中順序讀取各種信息並存入INSTANCE_CLASS結構中的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved