From 07e4f5234e51d51a108327aeb96f661fc14cd436 Mon Sep 17 00:00:00 2001 From: cacao Date: Mon, 2 Nov 1998 17:01:47 +0000 Subject: [PATCH 1/1] bidirectional layout of vftbl/interfaces added --- Makefile | 8 +- builtin.c | 98 +++------ builtin.h | 19 +- global.h | 388 ++++++++++++++++----------------- headers.c | 41 ++-- loader.c | 509 +++++++++++++++++++++++-------------------- src/cacaoh/headers.c | 41 ++-- src/vm/builtin.c | 98 +++------ src/vm/builtin.h | 19 +- src/vm/global.h | 388 ++++++++++++++++----------------- src/vm/loader.c | 509 +++++++++++++++++++++++-------------------- 11 files changed, 1046 insertions(+), 1072 deletions(-) diff --git a/Makefile b/Makefile index 3d32a7353..ab19725ea 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ # Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at # Andreas Krall EMAIL: cacao@complang.tuwien.ac.at # -# Last Change: 1998/09/27 +# Last Change: 1998/10/30 # # # ATTENTION: This version of the makefile only works with gmake. @@ -42,7 +42,7 @@ THREAD_OBJ = THREAD_CFLAGS = endif -#CC = gcc +#CC = cc #CFLAGS = -g -mieee -Wall $(THREAD_CFLAGS) #CFLAGS = -mieee -O3 -Wall $(THREAD_CFLAGS) @@ -94,7 +94,7 @@ endif mm/mm.o: mm/*.[ch] mm/Makefile cd mm; make mm.o "USE_THREADS=$(USE_THREADS)" "CFLAGS=$(CFLAGS)" "CC=$(CC)" -asmpart.o: sysdep/asmpart.c +asmpart.o: sysdep/asmpart.c sysdep/offsets.h rm -f asmpart.s $(CC) -E sysdep/asmpart.c > asmpart.s $(CC) -c -o asmpart.o asmpart.s @@ -156,7 +156,7 @@ config-sparc: ##################### generation of NATIVE - header files ###################### -nativetypes.hh nativetable.hh : cacaoh +sysdep/offsets.h nativetypes.hh nativetable.hh : cacaoh ./cacaoh java.lang.Object \ java.lang.String \ java.lang.Class \ diff --git a/builtin.c b/builtin.c index 6e28c7c5d..5ffa051ca 100644 --- a/builtin.c +++ b/builtin.c @@ -1,4 +1,3 @@ -/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */ /****************************** builtin.c ************************************** Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst @@ -34,13 +33,10 @@ builtin_descriptor builtin_desc[] = { {(functionptr) builtin_instanceof, "instanceof"}, {(functionptr) builtin_checkcast, "checkcast"}, - {(functionptr) new_builtin_checkcast, "checkcast"}, - {(functionptr) new_builtin_checkclasscast, "checkclasscast"}, - {(functionptr) new_builtin_checkintercast, "checkintercast"}, {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"}, {(functionptr) builtin_checkarraycast, "checkarraycast"}, - {(functionptr) new_builtin_checkarraycast, "checkarraycast"}, - {(functionptr) new_builtin_aastore, "aastore"}, + {(functionptr) asm_builtin_checkarraycast, "checkarraycast"}, + {(functionptr) asm_builtin_aastore, "aastore"}, {(functionptr) builtin_new, "new"}, {(functionptr) builtin_anewarray, "anewarray"}, {(functionptr) builtin_newarray_array, "newarray_array"}, @@ -55,20 +51,20 @@ builtin_descriptor builtin_desc[] = { {(functionptr) builtin_displaymethodstart, "displaymethodstart"}, {(functionptr) builtin_displaymethodstop, "displaymethodstop"}, {(functionptr) builtin_monitorenter, "monitorenter"}, - {(functionptr) new_builtin_monitorenter, "monitorenter"}, + {(functionptr) asm_builtin_monitorenter, "monitorenter"}, {(functionptr) builtin_monitorexit, "monitorexit"}, - {(functionptr) new_builtin_monitorexit, "monitorexit"}, + {(functionptr) asm_builtin_monitorexit, "monitorexit"}, {(functionptr) builtin_idiv, "idiv"}, - {(functionptr) new_builtin_idiv, "idiv"}, + {(functionptr) asm_builtin_idiv, "idiv"}, {(functionptr) builtin_irem, "irem"}, - {(functionptr) new_builtin_irem, "irem"}, + {(functionptr) asm_builtin_irem, "irem"}, {(functionptr) builtin_ladd, "ladd"}, {(functionptr) builtin_lsub, "lsub"}, {(functionptr) builtin_lmul, "lmul"}, {(functionptr) builtin_ldiv, "ldiv"}, - {(functionptr) new_builtin_ldiv, "ldiv"}, + {(functionptr) asm_builtin_ldiv, "ldiv"}, {(functionptr) builtin_lrem, "lrem"}, - {(functionptr) new_builtin_lrem, "lrem"}, + {(functionptr) asm_builtin_lrem, "lrem"}, {(functionptr) builtin_lshl, "lshl"}, {(functionptr) builtin_lshr, "lshr"}, {(functionptr) builtin_lushr, "lushr"}, @@ -127,13 +123,12 @@ builtin_descriptor builtin_desc[] = { static s4 builtin_isanysubclass (classinfo *sub, classinfo *super) { - if (super->flags & ACC_INTERFACE) { - s4 index = super->index; - if (index >= sub->vftbl->interfacetablelength) return 0; - return ( sub->vftbl->interfacevftbl[index] ) ? 1 : 0; - } - return (sub->vftbl->lowclassval >= super->vftbl->lowclassval) & - (sub->vftbl->lowclassval <= super->vftbl->highclassval); + if (super->flags & ACC_INTERFACE) + return (sub->vftbl->interfacetablelength > super->index) && + (sub->vftbl->interfacetable[-super->index] != NULL); + + return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <= + (unsigned) (super->vftbl->diffval); } @@ -175,53 +170,19 @@ s4 builtin_checkcast(java_objectheader *obj, classinfo *class) log_text ("builtin_checkcast called"); #endif - if (!obj) return 1; - if ( builtin_isanysubclass (obj->vftbl->class, class) ) { + if (obj == NULL) return 1; - } -#if DEBUG - printf ("#### checkcast failed "); - unicode_display (obj->vftbl->class->name); - printf (" -> "); - unicode_display (class->name); - printf ("\n"); -#endif - - return 0; -} - - -/***************** function: builtin_checkclasscast **************************** - - Returns 1 (true) if the object "sub" is a subclass of the class "super", - otherwise returns 0 (false). If sub is NULL it also returns 1 (true). - -*******************************************************************************/ - -s4 builtin_checkclasscast(java_objectheader *sub, classinfo *super) -{ - if (!sub) + if (builtin_isanysubclass (obj->vftbl->class, class)) return 1; - return (sub->vftbl->lowclassval >= super->vftbl->lowclassval) & - (sub->vftbl->lowclassval <= super->vftbl->highclassval); -} - - -/***************** function: builtin_checkintercast **************************** - - Returns 1 (true) if the object "sub" is a subclass of the interface "super", - otherwise returns 0 (false). If "sub" is NULL it also returns 1 (true). - -*******************************************************************************/ - -s4 builtin_checkintercast(java_objectheader *sub, classinfo *super) -{ - if (!sub) - return 1; +#if DEBUG + printf ("#### checkcast failed "); + unicode_display (obj->vftbl->class->name); + printf (" -> "); + unicode_display (class->name); + printf ("\n"); +#endif - return (sub->vftbl->interfacetablelength > super->index) && - (sub->vftbl->interfacevftbl[super->index] != NULL); return 0; } @@ -1649,3 +1610,16 @@ float builtin_d2f (double a) } } + +/* + * These are local overrides for various environment variables in Emacs. + * Please do not remove this and leave it at the end of the file, where + * Emacs will automagically detect them. + * --------------------------------------------------------------------- + * Local variables: + * mode: c + * indent-tabs-mode: t + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ diff --git a/builtin.h b/builtin.h index 1343c63eb..9fcae7ddd 100644 --- a/builtin.h +++ b/builtin.h @@ -25,14 +25,11 @@ extern builtin_descriptor builtin_desc[]; s4 builtin_instanceof(java_objectheader *obj, classinfo *class); s4 builtin_checkcast(java_objectheader *obj, classinfo *class); -s4 new_builtin_checkcast(java_objectheader *obj, classinfo *class); -s4 new_builtin_checkclasscast(java_objectheader *obj, classinfo *class); -s4 new_builtin_checkintercast(java_objectheader *obj, classinfo *class); s4 builtin_arrayinstanceof (java_objectheader *obj, constant_arraydescriptor *desc); s4 builtin_checkarraycast (java_objectheader *obj, constant_arraydescriptor *desc); -s4 new_builtin_checkarraycast +s4 asm_builtin_checkarraycast (java_objectheader *obj, constant_arraydescriptor *desc); java_objectheader *builtin_throw_exception (java_objectheader *exception); @@ -60,7 +57,7 @@ java_arrayheader *builtin_nmultianewarray (int size, s4 builtin_canstore (java_objectarray *a, java_objectheader *o); s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o); -void new_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o); +void asm_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o); void builtin_trace_args(long a0, long a1, long a2, long a3, long a4, long a5, methodinfo *method); void builtin_displaymethodstart(methodinfo *method); @@ -69,22 +66,22 @@ void builtin_displaymethodstop(methodinfo *method, long l, double d); void builtin_displaymethodexception(methodinfo *method); void builtin_monitorenter (java_objectheader *o); -void new_builtin_monitorenter (java_objectheader *o); +void asm_builtin_monitorenter (java_objectheader *o); void builtin_monitorexit (java_objectheader *o); -void new_builtin_monitorexit (java_objectheader *o); +void asm_builtin_monitorexit (java_objectheader *o); s4 builtin_idiv (s4 a, s4 b); -s4 new_builtin_idiv (s4 a, s4 b); +s4 asm_builtin_idiv (s4 a, s4 b); s4 builtin_irem (s4 a, s4 b); -s4 new_builtin_irem (s4 a, s4 b); +s4 asm_builtin_irem (s4 a, s4 b); s8 builtin_ladd (s8 a, s8 b); s8 builtin_lsub (s8 a, s8 b); s8 builtin_lmul (s8 a, s8 b); s8 builtin_ldiv (s8 a, s8 b); -s8 new_builtin_ldiv (s8 a, s8 b); +s8 asm_builtin_ldiv (s8 a, s8 b); s8 builtin_lrem (s8 a, s8 b); -s8 new_builtin_lrem (s8 a, s8 b); +s8 asm_builtin_lrem (s8 a, s8 b); s8 builtin_lshl (s8 a, s4 b); s8 builtin_lshr (s8 a, s4 b); s8 builtin_lushr (s8 a, s4 b); diff --git a/global.h b/global.h index 8b7995c56..df11a012c 100644 --- a/global.h +++ b/global.h @@ -1,4 +1,4 @@ -/****************************** global.h *************************************** +/* global.h ******************************************************************** Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst @@ -7,10 +7,10 @@ Contains global definitions which are used in the whole program, includes some files and contains global used macros. - Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at - Changes: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at - Mark Probst EMAIL: cacao@complang.tuwien.ac.at - Philipp Tomsich EMAIL: cacao@complang.tuwien.ac.at + Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at + Andreas Krall (andi) EMAIL: cacao@complang.tuwien.ac.at + Changes: Mark Probst (schani) EMAIL: cacao@complang.tuwien.ac.at + Philipp Tomsich (phil) EMAIL: cacao@complang.tuwien.ac.at Last Change: 1998/10/30 @@ -25,7 +25,7 @@ marker functions on and off. */ #undef JIT_MARKER_SUPPORT /* phil */ -/***************************** standard includes ******************************/ +/* standard includes **********************************************************/ #include #include @@ -38,17 +38,16 @@ #include "toolbox/loging.h" -/**************************** system dependent types **************************/ +/* system dependent types *****************************************************/ #include "sysdep/types.h" -/**************************** additional data types ***************************/ +/* additional data types ******************************************************/ typedef void *voidptr; /* generic pointer */ - -typedef u1 bool; /* boolean data type */ +typedef int bool; /* boolean data type */ #define true 1 #define false 0 @@ -59,43 +58,42 @@ typedef void (*functionptr) (); /* generic function pointer */ #define MAX_ALIGN 8 /* most generic alignment for JavaVM values */ -/**************************** shutdown function *******************************/ +/* shutdown function **********************************************************/ void cacao_shutdown(s4 status); -/**************************** basic data types ********************************/ +/* basic data types ***********************************************************/ #define TYPE_INT 0 /* the JavaVM types must numbered in the */ #define TYPE_LONG 1 /* same order as the ICMD_Ixxx to ICMD_Axxx */ #define TYPE_FLOAT 2 /* instructions (LOAD and STORE) */ #define TYPE_DOUBLE 3 /* integer, long, float, double, address */ -#define TYPE_ADDRESS 4 /* all other types can be numbered arbitrarily*/ +#define TYPE_ADDRESS 4 /* all other types can be numbered arbitrarly */ #define TYPE_VOID 10 -/**************************** Java class file constants ***********************/ +/* Java class file constants **************************************************/ #define MAGIC 0xcafebabe #define MINOR_VERSION 3 #define MAJOR_VERSION 45 -#define CONSTANT_Class 7 -#define CONSTANT_Fieldref 9 -#define CONSTANT_Methodref 10 -#define CONSTANT_InterfaceMethodref 11 -#define CONSTANT_String 8 -#define CONSTANT_Integer 3 -#define CONSTANT_Float 4 -#define CONSTANT_Long 5 -#define CONSTANT_Double 6 -#define CONSTANT_NameAndType 12 -#define CONSTANT_Utf8 1 - -#define CONSTANT_Arraydescriptor 13 -#define CONSTANT_UNUSED 0 - +#define CONSTANT_Class 7 +#define CONSTANT_Fieldref 9 +#define CONSTANT_Methodref 10 +#define CONSTANT_InterfaceMethodref 11 +#define CONSTANT_String 8 +#define CONSTANT_Integer 3 +#define CONSTANT_Float 4 +#define CONSTANT_Long 5 +#define CONSTANT_Double 6 +#define CONSTANT_NameAndType 12 +#define CONSTANT_Utf8 1 + +#define CONSTANT_Arraydescriptor 13 +#define CONSTANT_UNUSED 0 #define ACC_PUBLIC 0x0001 #define ACC_PRIVATE 0x0002 @@ -110,67 +108,90 @@ void cacao_shutdown(s4 status); #define ACC_ABSTRACT 0x0400 - -/**************************** resolve typedef-cycles **************************/ +/* resolve typedef cycles *****************************************************/ typedef struct unicode unicode; +typedef struct java_objectheader java_objectheader; typedef struct classinfo classinfo; typedef struct vftbl vftbl; typedef u1* methodptr; -/********************** data structures of UNICODE symbol *********************/ +/* constant pool entries ******************************************************* -struct unicode { - unicode *hashlink; /* externe Verkettung f"ur die unicode-Hashtabelle */ - u4 key; /* Hash-Schl"ussel (h"angt nur vom Text ab) */ - int length; /* L"ange des Textes */ - u2 *text; /* Zeiger auf den Text (jeder Buchstabe 16 Bit) */ - classinfo *class; /* gegebenenfalls Referenz auf die Klasse dieses - Namens (oder NULL, wenn es keine solche gibt) */ - struct java_objectheader *string; - /* gegebenenfalls Referenz auf einen konstanten - String mit dem entsprechenden Wert */ -}; + All constant pool entries need a data structure which contain the entrys + value. In some cases this structure exist already, in the remaining cases + this structure must be generated: -/* Alle Unicode-Symbole werden in einer einzigen globalen Tabelle - (Hashtabelle) verwaltet, jedes Symbol wird nur einmal angelegt. - -> Speicherersparnis, und "Uberpr"ufung auf Gleichheit durch einfachen - Zeigervergleich */ + kind structure generated? + ---------------------------------------------------------------------- + CONSTANT_Class classinfo no + CONSTANT_Fieldref constant_FMIref yes + CONSTANT_Methodref constant_FMIref yes + CONSTANT_InterfaceMethodref constant_FMIref yes + CONSTANT_String unicode no + CONSTANT_Integer constant_integer yes + CONSTANT_Float constant_float yes + CONSTANT_Long constant_long yes + CONSTANT_Double constant_double yes + CONSTANT_NameAndType constant_nameandtype yes + CONSTANT_Utf8 unicode no + CONSTANT_Arraydescriptor constant_arraydescriptor yes + CONSTANT_UNUSED - +*******************************************************************************/ -/************ data structures of remaining constant pool entries **************/ +/* data structures of Unicode symbol ******************************************* + All Unicode symbols are stored in one global (hash) table, every symbol + exists only once. Equal symbols have identical pointers. +*/ + +struct unicode { + unicode *hashlink; /* link for external hash chain */ + u4 key; /* hash key (computed from text) */ + int length; /* text length */ + u2 *text; /* pointer to text (each character is 16 Bit) */ + classinfo *class; /* class pointer if it exists, otherwise NULL */ + java_objectheader *string; /* string pointer if it exists, otherwise NULL*/ +}; -typedef struct { - classinfo *class; - unicode *name; - unicode *descriptor; -} constant_FMIref; +/* data structures of remaining constant pool entries *************************/ -typedef struct { +typedef struct { /* Fieldref, Methodref and InterfaceMethodref */ + classinfo *class; /* class containing this field/method/interface */ + unicode *name; /* field/method/interface name */ + unicode *descriptor; /* field/method/interface type descriptor string */ +} constant_FMIref; + +typedef struct { /* Integer */ s4 value; } constant_integer; -typedef struct { +typedef struct { /* Float */ float value; } constant_float; -typedef struct { +typedef struct { /* Long */ s8 value; } constant_long; -typedef struct { +typedef struct { /* Double */ double value; } constant_double; - -typedef struct { - unicode *name; - unicode *descriptor; +typedef struct { /* NameAndType (Field or Method) */ + unicode *name; /* field/method name */ + unicode *descriptor; /* field/method type descriptor string */ } constant_nameandtype; +/* arraydescriptor describes array types. Basic array types contain their + type in the arraytype field, objectclass contains a class pointer for + arrays of objects (arraytype == ARRAYTYPE_OBJECT), elementdescriptor + contains a pointer to an arraydescriptor which describes the element + types in the case of arrays of arrays (arraytype == ARRAYTYPE_ARRAY). +*/ typedef struct constant_arraydescriptor { int arraytype; @@ -178,75 +199,28 @@ typedef struct constant_arraydescriptor { struct constant_arraydescriptor *elementdescriptor; } constant_arraydescriptor; -/* Mit einem Arraydescriptor kann ein Array-Typ dargestellt werden. - Bei normalen Arrays (z.B. Array von Bytes,...) gen"ugt dazu, - dass das Feld arraytype die entsprechende Kennzahl enth"alt - (z.B. ARRAYTYPE_BYTE). - Bei Arrays von Objekten (arraytype=ARRAYTYPE_OBJECT) muss das - Feld objectclass auf die Klassenstruktur der m"oglichen - Element-Objekte zeigen. - Bei Arrays von Arrays (arraytype=ARRAYTYPE_ARRAY) muss das - Feld elementdescriptor auf eine weiter arraydescriptor-Struktur - zeigen, die die Element-Typen beschreibt. - */ - - - -/********* Anmerkungen zum Constant-Pool: - - Die Typen der Eintr"age in den Constant-Pool werden durch die oben - definierten CONSTANT_.. Werte angegeben. - Bei allen Typen muss zus"atzlich noch eine Datenstruktur hinzugef"ugt - werden, die den wirklichen Wert angibt. - Bei manchen Typen reicht es, einen Verweis auf eine schon bereits - existierende Struktur (z.B. unicode-Texte) einzutragen, bei anderen - muss diese Struktur erst extra erzeugt werden. - Ich habe folgende Datenstrukturen f"ur diese Typen verwendet: - - Typ Struktur extra erzeugt? - ---------------------------------------------------------------------- - CONSTANT_Class classinfo nein - CONSTANT_Fieldref constant_FMIref ja - CONSTANT_Methodref constant_FMIref ja - CONSTANT_InterfaceMethodref constant_FMIref ja - CONSTANT_String unicode nein - CONSTANT_Integer constant_integer ja - CONSTANT_Float constant_float ja - CONSTANT_Long constant_long ja - CONSTANT_Double constant_double ja - CONSTANT_NameAndType constant_nameandtype ja - CONSTANT_Utf8 unicode nein - CONSTANT_Arraydescriptor constant_arraydescriptor ja - CONSTANT_UNUSED - - -*******************************/ - +/* data structures of the runtime system **************************************/ -/***************** Die Datenstrukturen fuer das Laufzeitsystem ****************/ +/* objects ********************************************************************* + All objects (and arrays) which resides on the heap need the following + header at the beginning of the data structure. +*/ - /********* Objekte ********** - - Alle Objekte (und Arrays), die am Heap gespeichert werden, m"ussen eine - folgende spezielle Datenstruktur ganz vorne stehen haben: - - */ +struct java_objectheader { /* header for all objects */ + vftbl *vftbl; /* pointer to virtual function table */ +}; -typedef struct java_objectheader { /* Der Header f"ur alle Objekte */ - vftbl *vftbl; /* Zeiger auf die Function Table */ -} java_objectheader; +/* arrays ********************************************************************** -/********* Arrays *********** - - Alle Arrays in Java sind auch gleichzeitig Objekte (d.h. sie haben auch - den obligatorischen Object-Header und darin einen Verweis auf eine Klasse) - Es gibt aber (der Einfachheit halber) nur eine einzige Klasse f"ur alle - m"oglichen Typen von Arrays, deshalb wird der tats"achliche Typ in einem - Feld im Array-Objekt selbst gespeichert. - Die Typen sind: */ + All arrays are objects (they need the object header with a pointer to a + vvftbl (array class table). There is only one class for all arrays. The + type of an array is stored directly in the array object. Following types + are defined: +*/ #define ARRAYTYPE_INT 0 #define ARRAYTYPE_LONG 1 @@ -259,18 +233,15 @@ typedef struct java_objectheader { /* Der Header f"ur alle Objekte */ #define ARRAYTYPE_OBJECT 8 #define ARRAYTYPE_ARRAY 9 - -/** Der Header f"ur ein Java-Array **/ - -typedef struct java_arrayheader { /* Der Arrayheader f"ur alle Arrays */ - java_objectheader objheader; /* Der Object-Header */ - s4 size; /* Gr"osse des Arrays */ - s4 arraytype; /* Typ der Elemente */ +typedef struct java_arrayheader { /* header for all arrays */ + java_objectheader objheader; /* object header */ + s4 size; /* array size */ + s4 arraytype; /* array type from previous list */ } java_arrayheader; -/** Die Unterschiedlichen Strukturen f"ur alle Typen von Arrays **/ +/* structs for all kinds of arrays ********************************************/ typedef struct java_chararray { java_arrayheader header; @@ -287,10 +258,8 @@ typedef struct java_doublearray { double data[1]; } java_doublearray; - -/* achtung: die beiden Stukturen booleanarray und bytearray m"ussen - identisches memory-layout haben, weil mit den selben Funktionen - darauf zugegriffen wird */ +/* booleanarray and bytearray need identical memory layout (access methods + use the same machine code */ typedef struct java_booleanarray { java_arrayheader header; @@ -317,10 +286,8 @@ typedef struct java_longarray { s8 data[1]; } java_longarray; - -/* ACHTUNG: die beiden folgenden Strukturen m"ussen unbedingt gleiches - Memory-Layout haben, weil mit ein und der selben Funktion auf die - data-Eintr"age beider Typen zugegriffen wird !!!! */ +/* objectarray and arrayarray need identical memory layout (access methods + use the same machine code */ typedef struct java_objectarray { java_arrayheader header; @@ -335,12 +302,9 @@ typedef struct java_arrayarray { } java_arrayarray; +/* field, method and class structures *****************************************/ - -/******************** class, field and method structures **********************/ - - -/********************** structure: fieldinfo **********************************/ +/* fieldinfo ******************************************************************/ typedef struct fieldinfo {/* field of a class */ s4 flags; /* ACC flags */ @@ -361,7 +325,7 @@ typedef struct fieldinfo {/* field of a class */ } fieldinfo; -/********************** structure: exceptiontable *****************************/ +/* exceptiontable *************************************************************/ typedef struct exceptiontable { /* exceptiontable entry in a method */ s4 startpc; /* start pc of guarded area (inclusive) */ @@ -371,7 +335,7 @@ typedef struct exceptiontable { /* exceptiontable entry in a method */ } exceptiontable; -/********************** structure: methodinfo *********************************/ +/* methodinfo *****************************************************************/ typedef struct methodinfo { /* method structure */ s4 flags; /* ACC flags */ @@ -381,25 +345,25 @@ typedef struct methodinfo { /* method structure */ s4 paramcount; /* only temporary valid, parameter count */ u1 *paramtypes; /* only temporary valid, parameter types */ classinfo *class; /* class, the method belongs to */ - u4 vftblindex; /* index of method in virtual function table + s4 vftblindex; /* index of method in virtual function table (if it is a virtual method) */ s4 maxstack; /* maximum stack depth of method */ s4 maxlocals; /* maximum number of local variables */ - u4 jcodelength; /* length of JavaVM code */ + s4 jcodelength; /* length of JavaVM code */ u1 *jcode; /* pointer to JavaVM code */ s4 exceptiontablelength;/* exceptiontable length */ exceptiontable *exceptiontable; /* the exceptiontable */ u1 *stubroutine; /* stub for compiling or calling natives */ - u4 mcodelength; /* legth of generated machine code */ + s4 mcodelength; /* legth of generated machine code */ u1 *mcode; /* pointer to machine code */ u1 *entrypoint; /* entry point in machine code */ } methodinfo; -/********************** structure: classinfo **********************************/ +/* classinfo ******************************************************************/ struct classinfo { /* class structure */ java_objectheader header; /* classes are also objects */ @@ -439,66 +403,84 @@ struct classinfo { /* class structure */ methodinfo *marker; #endif }; + + +/* virtual function table ****************************************************** + + The vtbl has a bidirectional layout with open ends at both sides. + interfacetablelength gives the number of entries of the interface table at + the start of the vftbl. The vftbl pointer points to &interfacetable[0]. + vftbllength gives the number of entries of table at the end of the vftbl. + + runtime type check (checkcast): + + Different methods are used for runtime type check depending on the + argument of checkcast/instanceof. + A check against a class is implemented via relative numbering on the class + hierachy tree. The tree is numbered in a depth first traversal setting + the base field and the diff field. The diff field gets the result of + (high - base) so that a range check can be implemented by an unsigned + compare. A sub type test is done by checking the inclusion of base of + the sub class in the range of the superclass. + + A check against an interface is implemented via the interfacevftbl. If the + interfacevftbl contains a nonnull value a class is a subclass of this + interface. + + interfacetable: + + Like standard virtual methods interface methods are called using + virtual function tables. All interfaces are numbered sequentially + (starting with zero). For each class there exist an interface table + of virtual function tables for each implemented interface. The length + of the interface table is determined by the highest number of an + implemented interface. + + The following example assumes a class which implements interface 0 and 3: + + interfacetablelength = 4 + + | ... | +----------+ + +-----------+ | method 2 |---> method z + | class | | method 1 |---> method y + +-----------+ | method 0 |---> method x + | ivftbl 0 |----------> +----------+ + vftblptr ---> +-----------+ + | ivftbl -1 |--> NULL +----------+ + | ivftbl -2 |--> NULL | method 1 |---> method x + | ivftbl -3 |-----+ | method 0 |---> method a + +-----------+ +----> +----------+ + + +---------------+ + | length 3 = 2 | + | length 2 = 0 | + | length 1 = 0 | + | length 0 = 3 | + interfacevftbllength ---> +---------------+ + +*******************************************************************************/ struct vftbl { - classinfo *class; /* Class, the function table belongs to */ + methodptr *interfacetable[1]; /* interface table (access via macro) */ + + classinfo *class; /* class, the vtbl belongs to */ - s4 vftbllength; /* virtual function table length */ - s4 interfacetablelength; /* interface table length */ + s4 vftbllength; /* virtual function table length */ + s4 interfacetablelength; /* interface table length */ - s4 lowclassval; /* low value for relative numbering */ - s4 highclassval; /* high value for relative numbering */ + s4 baseval; /* base for runtime type check */ + s4 diffval; /* high - base for runtime type check */ - u4 *interfacevftbllength; /* see description below */ - methodptr **interfacevftbl; + s4 *interfacevftbllength; /* length of interface vftbls */ - methodptr table[1]; + methodptr table[1]; /* class vftbl */ }; -/*********** Anmerkungen zur Interfacetable: - - "Ahnlich wie die 'normalen' virtuellen Methoden k"onnen auch die - Interface-Methoden mit Hilfe einer Art Virtual Function Table - aufgerufen werden. - Dazu werden alle Interfaces im System fortlaufend nummeriert (beginnend - bei 0), und f"ur jede Klasse wird eine ganze Tabelle von - Virtual Function Tables erzeugt, n"amlich zu jedem Interface, das die - Klasse implementiert, eine. - - z.B. Nehmen wir an, eine Klasse implementiert zwei Interfaces (die durch - die Nummerierung die Indizes 0 und 3 bekommen haben) - - Das sieht dann ungef"ahr so aus: - -------------- ------------- - interfacevftbl ---> | Eintrag 0 |---------> | Methode 0 |---> Methode X - | Eintrag 1 |--> NULL | Methode 1 |---> Methode Y - | Eintrag 2 |--> NULL | Methode 2 |---> Methode Z - | Eintrag 3 |-----+ ------------- - -------------- | - +---> ------------- - | Methode 0 |---> Methode X - | Methode 1 |---> Methode A - ------------- - --------------- - interfacevftlblength ---> | Wert 0 = 3 | - | Wert 1 = 0 | - | Wert 2 = 0 | - | Wert 3 = 2 | - --------------- - - Der Aufruf einer Interface-Methode geht dann so vor sich: - Zur Compilezeit steht der Index (i) des Interfaces und die Stelle (s), wo - in der entsprechenden Untertabelle die Methode eingetragen ist, schon fest. - Also muss zur Laufzeit nur mehr der n-te Eintrag aus der Interfacetable - gelesen werden, von dieser Tabelle aus wird der s-te Eintrag geholt, - und diese Methode wird angesprungen. - -****************/ - - - -/********************** references to some system classes ********************/ +#define VFTBLINTERFACETABLE(v,i) (v)->interfacetable[-i] + + +/* references to some system classes ******************************************/ extern classinfo *class_java_lang_Object; extern classinfo *class_java_lang_String; @@ -514,7 +496,7 @@ extern classinfo *class_java_lang_ThreadDeath; extern classinfo *class_array; -/********************** instances of some system classes **********************/ +/* instances of some system classes *******************************************/ extern java_objectheader *proto_java_lang_ClassCastException; extern java_objectheader *proto_java_lang_NullPointerException; @@ -526,14 +508,14 @@ extern java_objectheader *proto_java_lang_ArrayStoreException; extern java_objectheader *proto_java_lang_ThreadDeath; -/******************************* flag variables *******************************/ +/* flag variables *************************************************************/ extern bool compileall; extern bool runverbose; extern bool verbose; -/******************************* trace variables ******************************/ +/* statistic variables ********************************************************/ extern int count_class_infos; extern int count_const_pool_len; diff --git a/headers.c b/headers.c index 92ae36898..d28baccef 100644 --- a/headers.c +++ b/headers.c @@ -45,26 +45,20 @@ void asm_call_jit_compiler () { } void asm_calljavamethod () { } void asm_dumpregistersandcall () { } -s4 new_builtin_idiv (s4 a, s4 b) {return 0;} -s4 new_builtin_irem (s4 a, s4 b) {return 0;} -s8 new_builtin_ldiv (s8 a, s8 b) {return 0;} -s8 new_builtin_lrem (s8 a, s8 b) {return 0;} - - -void new_builtin_monitorenter (java_objectheader *o) {} -void new_builtin_monitorexit (java_objectheader *o) {} - -s4 new_builtin_checkcast(java_objectheader *o, classinfo *c) - {return 0;} -s4 new_builtin_checkclasscast(java_objectheader *o, classinfo *c) - {return 0;} -s4 new_builtin_checkintercast(java_objectheader *o, classinfo *c) - {return 0;} -s4 new_builtin_checkarraycast +s4 asm_builtin_idiv (s4 a, s4 b) {return 0;} +s4 asm_builtin_irem (s4 a, s4 b) {return 0;} +s8 asm_builtin_ldiv (s8 a, s8 b) {return 0;} +s8 asm_builtin_lrem (s8 a, s8 b) {return 0;} + + +void asm_builtin_monitorenter (java_objectheader *o) {} +void asm_builtin_monitorexit (java_objectheader *o) {} + +s4 asm_builtin_checkarraycast (java_objectheader *o, constant_arraydescriptor *d) {return 0;} -void new_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o) {} +void asm_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o) {} u1 *createcompilerstub (methodinfo *m) {return NULL;} u1 *createnativestub (functionptr f, methodinfo *m) {return NULL;} @@ -422,6 +416,19 @@ int main(int argc, char **argv) log_init (NULL); log_text ("Java - header-generator started"); + file = fopen("sysdep/offsets.h", "w"); + if (file == NULL) + panic ("Can not open file 'sysdep/offsets.h' for write"); + + fprintf (file, "/* This file is machine generated, don't edit it !*/\n\n"); + + fprintf (file, "#define offobjvftbl %3d\n", (int) OFFSET(java_objectheader, vftbl)); + fprintf (file, "#define offarraysize %3d\n", (int) OFFSET(java_arrayheader, size)); + fprintf (file, "#define offobjarrdata %3d\n\n", (int) OFFSET(java_objectarray, data[0])); + fprintf (file, "#define offbaseval %3d\n", (int) OFFSET(vftbl, baseval)); + fprintf (file, "#define offdiffval %3d\n", (int) OFFSET(vftbl, diffval)); + + fclose (file); suck_init (classpath); diff --git a/loader.c b/loader.c index 38324b031..3927e3a7c 100644 --- a/loader.c +++ b/loader.c @@ -1,5 +1,4 @@ -/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */ -/****************************** loader.c *************************************** +/* loader.c ******************************************************************** Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst @@ -29,18 +28,18 @@ #include "threads/thread.h" /* schani */ -/*************************** globale Variablen *******************************/ +/* global variables ***********************************************************/ -extern bool newcompiler; +extern bool newcompiler; /* true if new compiler is used */ -int count_class_infos = 0; +int count_class_infos = 0; /* variables for measurements */ int count_const_pool_len = 0; int count_vftbl_len = 0; int count_all_methods = 0; int count_vmcode_len = 0; int count_extable_len = 0; -bool loadverbose = false; /* Switches f"ur mehr Debug-Meldungen */ +bool loadverbose = false; /* switches for debug messages */ bool linkverbose = false; bool initverbose = false; @@ -50,17 +49,15 @@ bool getloadingtime = false; long int loadingtime = 0; -static u4 interfaceindex; /* fortlaufende Nummer f"ur Interfaces */ +static s4 interfaceindex; /* sequential numbering of interfaces */ -static list unloadedclasses; /* Liste alle referenzierten, aber noch nicht - geladenen Klassen */ -static list unlinkedclasses; /* Liste aller geladenen, aber noch nicht - gelinkten Klassen */ - list linkedclasses; /* Liste aller fertig gelinkten Klassen */ +static list unloadedclasses; /* list of all referenced but not loaded classes */ +static list unlinkedclasses; /* list of all loaded but not linked classes */ + list linkedclasses; /* list of all completely linked classes */ -/***************** die Referenzen auf die wichtigen Systemklassen ************/ +/* important system classes ***************************************************/ classinfo *class_java_lang_Object; classinfo *class_java_lang_String; @@ -76,7 +73,7 @@ classinfo *class_java_lang_ThreadDeath; /* schani */ classinfo *class_array; -/************ einige vorgefertigte Instanzen wichtiger Systemklassen *********/ +/* instances of important system classes **************************************/ java_objectheader *proto_java_lang_ClassCastException; java_objectheader *proto_java_lang_NullPointerException; @@ -90,12 +87,12 @@ java_objectheader *proto_java_lang_ThreadDeath; /* schani */ -/****************************************************************************/ -/******************* Einige Support-Funkionen *******************************/ -/****************************************************************************/ +/******************************************************************************/ +/******************* Einige Support-Funkionen *********************************/ +/******************************************************************************/ -/********** interne Funktion: printflags (nur zu Debug-Zwecken) ************/ +/********** interne Funktion: printflags (nur zu Debug-Zwecken) **************/ static void printflags (u2 f) { @@ -113,56 +110,53 @@ static void printflags (u2 f) } -/************************* Funktion: skipattribute **************************** +/************************* Funktion: skipattribute ***************************** "uberliest im ClassFile eine (1) 'attribute'-Struktur -******************************************************************************/ +*******************************************************************************/ static void skipattribute () { - u4 len; - suck_u2 (); - len = suck_u4 (); - skip_nbytes (len); + skip_nbytes(suck_u4()); } -/********************** Funktion: skipattributebody *************************** +/********************** Funktion: skipattributebody **************************** "uberliest im Classfile ein attribut, wobei die 16-bit - attribute_name - Referenz schon gelesen worden ist. -******************************************************************************/ +*******************************************************************************/ static void skipattributebody () { - u4 len = suck_u4 (); - skip_nbytes (len); + skip_nbytes(suck_u4()); } -/************************* Funktion: skipattributes *************************** +/************************* Funktion: skipattributes **************************** "uberliest im ClassFile eine gew"unschte Anzahl von attribute-Strukturen -******************************************************************************/ +*******************************************************************************/ static void skipattributes (u4 num) { u4 i; - for (i=0; i linked = false; c -> index = 0; c -> instancesize = 0; + c -> header.vftbl = NULL; c -> vftbl = NULL; c -> initialized = false; @@ -717,12 +712,12 @@ classinfo *class_get (unicode *u) -/******************** Funktion: class_getconstant ***************************** +/******************** Funktion: class_getconstant ****************************** holt aus dem ConstantPool einer Klasse den Wert an der Stelle 'pos'. Der Wert mu"s vom Typ 'ctype' sein, sonst wird das System angehalten. -******************************************************************************/ +*******************************************************************************/ voidptr class_getconstant (classinfo *c, u4 pos, u4 ctype) { @@ -738,12 +733,12 @@ voidptr class_getconstant (classinfo *c, u4 pos, u4 ctype) } -/********************* Funktion: class_constanttype *************************** +/********************* Funktion: class_constanttype **************************** Findet heraus, welchen Typ ein Eintrag in den ConstantPool einer Klasse hat. -******************************************************************************/ +*******************************************************************************/ u4 class_constanttype (classinfo *c, u4 pos) { @@ -753,7 +748,7 @@ u4 class_constanttype (classinfo *c, u4 pos) } -/******************** Funktion: class_loadcpool ******************************* +/******************** Funktion: class_loadcpool ******************************** l"adt den gesammten ConstantPool einer Klasse. @@ -761,7 +756,7 @@ u4 class_constanttype (classinfo *c, u4 pos) Format gebracht (Klassenreferenzen werden aufgel"ost, ...) F"ur eine genaue "Ubersicht "uber das kompakte Format siehe: 'global.h' -******************************************************************************/ +*******************************************************************************/ static void class_loadcpool (classinfo *c) { @@ -1050,7 +1045,7 @@ static void class_loadcpool (classinfo *c) } -/********************** Funktion: class_load ********************************** +/********************** Funktion: class_load *********************************** l"adt alle Infos f"ur eine ganze Klasse aus einem ClassFile. Die 'classinfo'-Struktur mu"s bereits angelegt worden sein. @@ -1062,7 +1057,7 @@ static void class_loadcpool (classinfo *c) Die gelesene Klasse wird dann aus der Liste 'unloadedclasses' ausgetragen und in die Liste 'unlinkedclasses' eingh"angt. -******************************************************************************/ +*******************************************************************************/ static void class_load (classinfo *c) { @@ -1142,12 +1137,12 @@ static void class_load (classinfo *c) -/************** interne Funktion: class_highestinterface ********************** +/************** interne Funktion: class_highestinterface *********************** wird von der Funktion class_link ben"otigt, um festzustellen, wie gro"s die Interfacetable einer Klasse sein mu"s. -******************************************************************************/ +*******************************************************************************/ static s4 class_highestinterface (classinfo *c) { @@ -1169,46 +1164,47 @@ static s4 class_highestinterface (classinfo *c) } -/**************** Funktion: class_addinterface ******************************** +/* class_addinterface ********************************************************** wird von der Funktion class_link ben"otigt, um eine Virtual Function Table f"ur ein Interface (und alle weiteren von diesem Interface implementierten Interfaces) in eine Klasse einzutragen. -******************************************************************************/ +*******************************************************************************/ static void class_addinterface (classinfo *c, classinfo *ic) { - u4 i = ic->index; - u4 j,m; + s4 j, m; + s4 i = ic->index; vftbl *vftbl = c->vftbl; - if (i>=vftbl->interfacetablelength) panic ("Interfacetable-Overflow"); - if (vftbl->interfacevftbl[i]) return; + if (i >= vftbl->interfacetablelength) + panic ("Inernal error: interfacetable overflow"); + if (vftbl->interfacetable[-i]) + return; - if (ic->methodscount==0) { /* wenn interface keine Methoden hat, dann - trotzdem eine Tabelle mit L"ange 1 anlegen, - wegen Subclass-Tests */ - vftbl -> interfacevftbllength[i] = 1; - vftbl -> interfacevftbl[i] = MNEW(methodptr, 1); - vftbl -> interfacevftbl[i][0] = NULL; + if (ic->methodscount == 0) { /* fake entry needed for subtype test */ + vftbl->interfacevftbllength[i] = 1; + vftbl->interfacetable[-i] = MNEW(methodptr, 1); + vftbl->interfacetable[-i][0] = NULL; } else { - vftbl -> interfacevftbllength[i] = ic -> methodscount; - vftbl -> interfacevftbl[i] = MNEW(methodptr, ic -> methodscount); + vftbl->interfacevftbllength[i] = ic->methodscount; + vftbl->interfacetable[-i] = MNEW(methodptr, ic->methodscount); #ifdef STATISTICS - count_vftbl_len += sizeof(methodptr) * ic -> methodscount; + count_vftbl_len += sizeof(methodptr) * + (ic->methodscount + (ic->methodscount == 0)); #endif for (j=0; jmethodscount; j++) { classinfo *sc = c; while (sc) { - for (m=0; mmethodscount; m++) { + for (m = 0; m < sc->methodscount; m++) { methodinfo *mi = &(sc->methods[m]); - if (method_canoverwrite (mi, &(ic->methods[j])) ) { - vftbl->interfacevftbl[i][j] = - vftbl->table[mi->vftblindex]; + if (method_canoverwrite(mi, &(ic->methods[j]))) { + vftbl->interfacetable[-i][j] = + vftbl->table[mi->vftblindex]; goto foundmethod; } } @@ -1217,13 +1213,13 @@ static void class_addinterface (classinfo *c, classinfo *ic) foundmethod: ; } } - - for (j=0; jinterfacescount; j++) + + for (j = 0; j < ic->interfacescount; j++) class_addinterface(c, ic->interfaces[j]); } -/********************** Funktion: class_link ********************************** +/********************** Funktion: class_link *********************************** versucht, eine Klasse in das System voll zu integrieren (linken). Dazu m"ussen sowol die Superklasse, als auch alle implementierten @@ -1240,53 +1236,60 @@ static void class_addinterface (classinfo *c, classinfo *ic) Achtung: Bei zyklischen Klassendefinitionen ger"at das Programm hier in eine Endlosschleife!! (Da muss ich mir noch was einfallen lassen) -******************************************************************************/ +*******************************************************************************/ static void class_link (classinfo *c) { - u4 supervftbllength; /* L"ange der VFTBL der Superklasse */ - u4 vftbllength; /* L"ange der VFTBL dieser Klasse */ - classinfo *super = c->super; - classinfo *ic,*c2; /* Hilfsvariablen */ - vftbl *v; - u4 i; + s4 supervftbllength; /* vftbllegnth of super class */ + s4 vftbllength; /* vftbllength of current class */ + s4 interfacetablelength; /* interface table length */ + classinfo *super = c->super; /* super class */ + classinfo *ic, *c2; /* intermediate class variables */ + vftbl *v; /* vftbl of current class */ + s4 i; /* interface/method/field counter */ - /* schauen, ob alle "ubergeordneten Klassen schon fertig sind, - und richtiges Initialisieren der lokalen Variablen */ + /* check if all superclasses are already linked, if not put c at end of + unlinked list and return. Additionally initialize class fields. */ - for ( i=0; iinterfacescount; i++) { + /* check interfaces */ + + for (i = 0; i < c->interfacescount; i++) { ic = c->interfaces[i]; - if ( !ic -> linked) { - list_remove (&unlinkedclasses,c ); - list_addlast (&unlinkedclasses,c ); + if (!ic->linked) { + list_remove(&unlinkedclasses, c); + list_addlast(&unlinkedclasses, c); return; } } - if (! super) { - c -> index = 0; - c -> instancesize = sizeof (java_objectheader); + /* check super class */ + + if (super == NULL) { /* class java.long.Object */ + c->index = 0; + c->instancesize = sizeof(java_objectheader); vftbllength = supervftbllength = 0; - c -> finalizer = NULL; + c->finalizer = NULL; } else { - if ( !super -> linked ) { - list_remove (&unlinkedclasses,c ); - list_addlast (&unlinkedclasses,c ); + if (!super->linked) { + list_remove(&unlinkedclasses, c); + list_addlast(&unlinkedclasses, c); return; } - if ( c->flags & ACC_INTERFACE) c -> index = interfaceindex++; - else c -> index = super -> index + 1; + if (c->flags & ACC_INTERFACE) + c->index = interfaceindex++; + else + c->index = super->index + 1; - c -> instancesize = super -> instancesize; + c->instancesize = super->instancesize; - vftbllength = supervftbllength = super -> vftbl -> vftbllength; + vftbllength = supervftbllength = super->vftbl->vftbllength; - c -> finalizer = super -> finalizer; + c->finalizer = super->finalizer; } @@ -1296,25 +1299,25 @@ static void class_link (classinfo *c) dolog (); } - /* Erstellen der Virtual Function Table */ + /* compute vftbl length */ - for (i=0; i < c->methodscount; i++) { + for (i = 0; i < c->methodscount; i++) { methodinfo *m = &(c->methods[i]); - if (! (m->flags & ACC_STATIC) ) { + if (!(m->flags & ACC_STATIC)) { /* is instance method */ classinfo *sc = super; while (sc) { int j; - for (j=0; j < sc->methodscount; j++) { - if ( method_canoverwrite (m, &(sc->methods[j])) ) { - m -> vftblindex = sc->methods[j].vftblindex; + for (j = 0; j < sc->methodscount; j++) { + if (method_canoverwrite(m, &(sc->methods[j]))) { + m->vftblindex = sc->methods[j].vftblindex; goto foundvftblindex; } } sc = sc->super; } - m -> vftblindex = (vftbllength++); - foundvftblindex: ; + m->vftblindex = (vftbllength++); +foundvftblindex: ; } } @@ -1322,106 +1325,114 @@ static void class_link (classinfo *c) count_vftbl_len += sizeof(vftbl) + sizeof(methodptr)*(vftbllength-1); #endif - c -> vftbl = v = (vftbl*) - mem_alloc (sizeof(vftbl) + sizeof(methodptr)*(vftbllength-1)); - v -> class = c; - v -> vftbllength = vftbllength; - v -> interfacetablelength = 0; - - for (i=0; i < supervftbllength; i++) - v -> table[i] = super -> vftbl -> table[i]; + /* compute interfacetable length */ + + interfacetablelength = 0; + c2 = c; + while (c2) { + for (i = 0; i < c2->interfacescount; i++) { + s4 h = class_highestinterface (c2->interfaces[i]) + 1; + if (h > interfacetablelength) + interfacetablelength = h; + } + c2 = c2->super; + } + + /* allocate virtual function table */ + + v = (vftbl*) mem_alloc(sizeof(vftbl) + sizeof(methodptr) * + (vftbllength - 1) + sizeof(methodptr*) * + (interfacetablelength - (interfacetablelength > 0))); + v = (vftbl*) (((methodptr*) v) + (interfacetablelength - 1) * + (interfacetablelength > 1)); + c->header.vftbl = c->vftbl = v; + v->class = c; + v->vftbllength = vftbllength; + v->interfacetablelength = interfacetablelength; + + /* copy virtual function table of super class */ + + for (i = 0; i < supervftbllength; i++) + v->table[i] = super->vftbl->table[i]; - for (i=0; i < c->methodscount; i++) { + /* add method stubs into virtual function table */ + + for (i = 0; i < c->methodscount; i++) { methodinfo *m = &(c->methods[i]); - if ( ! (m->flags & ACC_STATIC) ) { - v -> table[m->vftblindex] = m -> stubroutine; + if (!(m->flags & ACC_STATIC)) { + v->table[m->vftblindex] = m->stubroutine; } } - - /* Berechnen der Instanzengr"o"se und der Offsets der einzelnen - Felder */ + /* compute instance size and offset of each field */ - for (i=0; i < c->fieldscount; i++) { - u4 dsize; - fieldinfo *f = &(c -> fields[i]); + for (i = 0; i < c->fieldscount; i++) { + s4 dsize; + fieldinfo *f = &(c->fields[i]); - if ( ! (f->flags & ACC_STATIC) ) { + if (!(f->flags & ACC_STATIC) ) { dsize = desc_typesize (f->descriptor); - c -> instancesize = ALIGN ( c->instancesize, dsize); - f -> offset = c -> instancesize; - c -> instancesize += dsize; + c->instancesize = ALIGN (c->instancesize, dsize); + f->offset = c->instancesize; + c->instancesize += dsize; } - } + /* initialize interfacetable and interfacevftbllength */ - /* Berechnen der Virtual Function Tables f"ur alle Interfaces */ - - c2 = c; - while (c2) { - for (i=0; iinterfacescount; i++) { - s4 h = class_highestinterface (c2->interfaces[i]) + 1; - if ( h > v->interfacetablelength) v->interfacetablelength = h; - } - c2 = c2->super; - } - v -> interfacevftbllength = MNEW (u4, v->interfacetablelength); - v -> interfacevftbl = MNEW (methodptr *, v->interfacetablelength); + v->interfacevftbllength = MNEW (s4, interfacetablelength); #ifdef STATISTICS - count_vftbl_len += (4 + sizeof(methodptr*)) * v->interfacetablelength; + count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength; #endif - for (i=0; i < v->interfacetablelength; i++) { - v -> interfacevftbllength[i] = 0; - v -> interfacevftbl[i] = NULL; + for (i = 0; i < interfacetablelength; i++) { + v->interfacevftbllength[i] = 0; + v->interfacetable[-i] = NULL; } - c2 = c; - while (c2) { - for (i=0; iinterfacescount; i++) { + /* add interfaces */ + + for (c2 = c; c2 != NULL; c2 = c2->super) + for (i = 0; i < c2->interfacescount; i++) { class_addinterface (c, c2->interfaces[i]); } - c2 = c2->super; - } - - - /* Die finalizer-Methode suchen und eintragen (wenn vorhanden), - aber nur bei Objekten ausser java.lang.Object */ + /* add finalizer method (not for java.lang.Object) */ - if (super) { + if (super != NULL) { methodinfo *fi; - static unicode *finame=NULL,*fidesc=NULL; - - if (!finame) finame = unicode_new_char ("finalize"); - if (!fidesc) fidesc = unicode_new_char ("()V"); + static unicode *finame = NULL; + static unicode *fidesc = NULL; + + if (finame == NULL) + finame = unicode_new_char("finalize"); + if (fidesc == NULL) + fidesc = unicode_new_char("()V"); fi = class_findmethod (c, finame, fidesc); - if (fi) { - if (! (fi->flags & ACC_STATIC) ) { - c -> finalizer = fi; + if (fi != NULL) { + if (!(fi->flags & ACC_STATIC)) { + c->finalizer = fi; } } - } - - - /* Abschlie"sende Aktionen */ - - c -> linked = true; + } + + /* final tasks */ + + c->linked = true; list_remove (&unlinkedclasses, c); list_addlast (&linkedclasses, c); } -/******************* Funktion: class_freepool ********************************* +/******************* Funktion: class_freepool ********************************** Gibt alle Resourcen, die der ConstantPool einer Klasse ben"otigt, wieder frei. -******************************************************************************/ +*******************************************************************************/ static void class_freecpool (classinfo *c) { @@ -1467,15 +1478,15 @@ static void class_freecpool (classinfo *c) } -/*********************** Funktion: class_free ********************************* +/*********************** Funktion: class_free ********************************** Gibt alle Resourcen, die eine ganze Klasse ben"otigt, frei -******************************************************************************/ +*******************************************************************************/ static void class_free (classinfo *c) { - u4 i; + s4 i; vftbl *v; unicode_unlinkclass (c->name); @@ -1484,38 +1495,44 @@ static void class_free (classinfo *c) MFREE (c->interfaces, classinfo*, c->interfacescount); - for (i=0; i < c->fieldscount; i++) field_free ( &(c->fields[i]) ); + for (i = 0; i < c->fieldscount; i++) + field_free(&(c->fields[i])); MFREE (c->fields, fieldinfo, c->fieldscount); - for (i=0; i < c->methodscount; i++) method_free ( &(c->methods[i]) ); + for (i = 0; i < c->methodscount; i++) + method_free(&(c->methods[i])); MFREE (c->methods, methodinfo, c->methodscount); - if ( (v = c->vftbl) ) { - for (i=0; iinterfacetablelength; i++) { - MFREE (v->interfacevftbl[i], methodptr, v->interfacevftbllength[i]); + if ((v = c->vftbl) != NULL) { + for (i = 0; i < v->interfacetablelength; i++) { + MFREE (v->interfacetable[-i], methodptr, v->interfacevftbllength[i]); } - MFREE (v->interfacevftbllength, u4, v->interfacetablelength); - MFREE (v->interfacevftbl, methodptr*, v->interfacetablelength); - - mem_free (v, sizeof(vftbl) + sizeof(methodptr) * (v->vftbllength - 1)); + MFREE (v->interfacevftbllength, s4, v->interfacetablelength); + + i = sizeof(vftbl) + sizeof(methodptr) * (v->vftbllength - 1) + + sizeof(methodptr*) * (v->interfacetablelength - + (v->interfacetablelength > 0)); + v = (vftbl*) (((methodptr*) v) - (v->interfacetablelength - 1) * + (v->interfacetablelength > 1)); + mem_free (v, i); } FREE (c, classinfo); } -/************************* Funktion: class_findfield ************************* +/************************* Funktion: class_findfield *************************** sucht in einer 'classinfo'-Struktur nach einem Feld mit gew"unschtem Namen und Typ. -*****************************************************************************/ +*******************************************************************************/ fieldinfo *class_findfield (classinfo *c, unicode *name, unicode *desc) { - u4 i; - for (i=0; i < c->fieldscount; i++) { - if ( (c->fields[i].name == name) && (c->fields[i].descriptor == desc) ) + s4 i; + for (i = 0; i < c->fieldscount; i++) { + if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) return &(c->fields[i]); } panic ("Can not find field given in CONSTANT_Fieldref"); @@ -1523,34 +1540,31 @@ fieldinfo *class_findfield (classinfo *c, unicode *name, unicode *desc) } -/************************* Funktion: class_findmethod ************************* +/************************* Funktion: class_findmethod ************************** sucht in einer 'classinfo'-Struktur nach einer Methode mit gew"unschtem Namen und Typ. Wenn als Typ NULL angegeben wird, dann ist der Typ egal. -*****************************************************************************/ +*******************************************************************************/ methodinfo *class_findmethod (classinfo *c, unicode *name, unicode *desc) { - u4 i; - for (i=0; i < c->methodscount; i++) { - if ( (c->methods[i].name == name) - && ( (desc == NULL) - || (c->methods[i].descriptor == desc) - ) - ) + s4 i; + for (i = 0; i < c->methodscount; i++) { + if ((c->methods[i].name == name) && ((desc == NULL) || + (c->methods[i].descriptor == desc))) return &(c->methods[i]); } return NULL; } -/************************* Funktion: class_resolvemethod ************************* +/************************* Funktion: class_resolvemethod *********************** sucht eine Klasse und alle Superklassen ab, um eine Methode zu finden. -*****************************************************************************/ +*******************************************************************************/ methodinfo *class_resolvemethod (classinfo *c, unicode *name, unicode *desc) @@ -1565,11 +1579,11 @@ methodinfo *class_resolvemethod (classinfo *c, unicode *name, unicode *desc) -/************************* Funktion: class_issubclass ************************ +/************************* Funktion: class_issubclass ************************** "uberpr"uft, ob eine Klasse von einer anderen Klasse abgeleitet ist. -*****************************************************************************/ +*******************************************************************************/ bool class_issubclass (classinfo *sub, classinfo *super) { @@ -1582,14 +1596,14 @@ bool class_issubclass (classinfo *sub, classinfo *super) -/****************** Initialisierungsfunktion f"ur eine Klasse **************** +/****************** Initialisierungsfunktion f"ur eine Klasse ****************** In Java kann jede Klasse ein statische Initialisierungsfunktion haben. Diese Funktion mu"s aufgerufen werden, BEVOR irgendwelche Methoden der Klasse aufgerufen werden, oder auf statische Variablen zugegriffen wird. -******************************************************************************/ +*******************************************************************************/ #ifdef USE_THREADS extern int blockInts; @@ -1660,7 +1674,7 @@ void class_init (classinfo *c) -/********* Funktion: class_showconstantpool (nur f"ur Debug-Zwecke) ********/ +/********* Funktion: class_showconstantpool (nur f"ur Debug-Zwecke) *********/ void class_showconstantpool (classinfo *c) { @@ -1752,11 +1766,11 @@ void class_showconstantpool (classinfo *c) -/********** Funktion: class_showmethods (nur f"ur Debug-Zwecke) ************/ +/********** Funktion: class_showmethods (nur f"ur Debug-Zwecke) *************/ void class_showmethods (classinfo *c) { - u4 i; + s4 i; printf ("--------- Fields and Methods ----------------\n"); printf ("Flags: "); printflags (c->flags); printf ("\n"); @@ -1798,18 +1812,18 @@ void class_showmethods (classinfo *c) -/*****************************************************************************/ -/******************* Funktionen fuer den Class-loader generell ***************/ -/*****************************************************************************/ +/******************************************************************************/ +/******************* Funktionen fuer den Class-loader generell ****************/ +/******************************************************************************/ -/********************* Funktion: loader_load ********************************** +/********************* Funktion: loader_load *********************************** l"adt und linkt die ge"unschte Klasse und alle davon referenzierten Klassen und Interfaces Return: Einen Zeiger auf diese Klasse -******************************************************************************/ +*******************************************************************************/ classinfo *loader_load (unicode *topname) { @@ -1842,11 +1856,11 @@ classinfo *loader_load (unicode *topname) } -/******************* interne Funktion: loader_createarrayclass **************** +/******************* interne Funktion: loader_createarrayclass ***************** Erzeugt (und linkt) eine Klasse f"ur die Arrays. -******************************************************************************/ +*******************************************************************************/ static classinfo *loader_createarrayclass () { @@ -1863,12 +1877,12 @@ static classinfo *loader_createarrayclass () -/********************** Funktion: loader_init ********************************* +/********************** Funktion: loader_init ********************************** Initialisiert alle Listen und l"adt alle Klassen, die vom System und vom Compiler direkt ben"otigt werden. -******************************************************************************/ +*******************************************************************************/ void loader_init () { @@ -1943,7 +1957,7 @@ void loader_init () initialisiert alle geladenen aber noch nicht initialisierten Klassen -******************************************************************************/ +*******************************************************************************/ void loader_initclasses () { @@ -1968,19 +1982,19 @@ static void loader_compute_class_values (classinfo *c) { classinfo *subs; - c->vftbl->lowclassval = classvalue++; + c->vftbl->baseval = ++classvalue; subs = c->sub; while (subs != NULL) { loader_compute_class_values(subs); subs = subs->nextsub; } - c->vftbl->highclassval = classvalue++; + c->vftbl->diffval = classvalue - c->vftbl->baseval; /* { int i; for (i = 0; i < c->index; i++) printf(" "); - printf("%3d %3d ", (int) c->vftbl->lowclassval, (int) c->vftbl->highclassval); + printf("%3d %3d ", (int) c->vftbl->baseval, c->vftbl->diffval); unicode_display(c->name); printf("\n"); } @@ -2010,11 +2024,11 @@ void loader_compute_subclasses () -/******************** Funktion: loader_close ********************************** +/******************** Funktion: loader_close *********************************** gibt alle Resourcen wieder frei -******************************************************************************/ +*******************************************************************************/ void loader_close () { @@ -2034,3 +2048,16 @@ void loader_close () } } + +/* + * These are local overrides for various environment variables in Emacs. + * Please do not remove this and leave it at the end of the file, where + * Emacs will automagically detect them. + * --------------------------------------------------------------------- + * Local variables: + * mode: c + * indent-tabs-mode: t + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ diff --git a/src/cacaoh/headers.c b/src/cacaoh/headers.c index 92ae36898..d28baccef 100644 --- a/src/cacaoh/headers.c +++ b/src/cacaoh/headers.c @@ -45,26 +45,20 @@ void asm_call_jit_compiler () { } void asm_calljavamethod () { } void asm_dumpregistersandcall () { } -s4 new_builtin_idiv (s4 a, s4 b) {return 0;} -s4 new_builtin_irem (s4 a, s4 b) {return 0;} -s8 new_builtin_ldiv (s8 a, s8 b) {return 0;} -s8 new_builtin_lrem (s8 a, s8 b) {return 0;} - - -void new_builtin_monitorenter (java_objectheader *o) {} -void new_builtin_monitorexit (java_objectheader *o) {} - -s4 new_builtin_checkcast(java_objectheader *o, classinfo *c) - {return 0;} -s4 new_builtin_checkclasscast(java_objectheader *o, classinfo *c) - {return 0;} -s4 new_builtin_checkintercast(java_objectheader *o, classinfo *c) - {return 0;} -s4 new_builtin_checkarraycast +s4 asm_builtin_idiv (s4 a, s4 b) {return 0;} +s4 asm_builtin_irem (s4 a, s4 b) {return 0;} +s8 asm_builtin_ldiv (s8 a, s8 b) {return 0;} +s8 asm_builtin_lrem (s8 a, s8 b) {return 0;} + + +void asm_builtin_monitorenter (java_objectheader *o) {} +void asm_builtin_monitorexit (java_objectheader *o) {} + +s4 asm_builtin_checkarraycast (java_objectheader *o, constant_arraydescriptor *d) {return 0;} -void new_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o) {} +void asm_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o) {} u1 *createcompilerstub (methodinfo *m) {return NULL;} u1 *createnativestub (functionptr f, methodinfo *m) {return NULL;} @@ -422,6 +416,19 @@ int main(int argc, char **argv) log_init (NULL); log_text ("Java - header-generator started"); + file = fopen("sysdep/offsets.h", "w"); + if (file == NULL) + panic ("Can not open file 'sysdep/offsets.h' for write"); + + fprintf (file, "/* This file is machine generated, don't edit it !*/\n\n"); + + fprintf (file, "#define offobjvftbl %3d\n", (int) OFFSET(java_objectheader, vftbl)); + fprintf (file, "#define offarraysize %3d\n", (int) OFFSET(java_arrayheader, size)); + fprintf (file, "#define offobjarrdata %3d\n\n", (int) OFFSET(java_objectarray, data[0])); + fprintf (file, "#define offbaseval %3d\n", (int) OFFSET(vftbl, baseval)); + fprintf (file, "#define offdiffval %3d\n", (int) OFFSET(vftbl, diffval)); + + fclose (file); suck_init (classpath); diff --git a/src/vm/builtin.c b/src/vm/builtin.c index 6e28c7c5d..5ffa051ca 100644 --- a/src/vm/builtin.c +++ b/src/vm/builtin.c @@ -1,4 +1,3 @@ -/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */ /****************************** builtin.c ************************************** Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst @@ -34,13 +33,10 @@ builtin_descriptor builtin_desc[] = { {(functionptr) builtin_instanceof, "instanceof"}, {(functionptr) builtin_checkcast, "checkcast"}, - {(functionptr) new_builtin_checkcast, "checkcast"}, - {(functionptr) new_builtin_checkclasscast, "checkclasscast"}, - {(functionptr) new_builtin_checkintercast, "checkintercast"}, {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"}, {(functionptr) builtin_checkarraycast, "checkarraycast"}, - {(functionptr) new_builtin_checkarraycast, "checkarraycast"}, - {(functionptr) new_builtin_aastore, "aastore"}, + {(functionptr) asm_builtin_checkarraycast, "checkarraycast"}, + {(functionptr) asm_builtin_aastore, "aastore"}, {(functionptr) builtin_new, "new"}, {(functionptr) builtin_anewarray, "anewarray"}, {(functionptr) builtin_newarray_array, "newarray_array"}, @@ -55,20 +51,20 @@ builtin_descriptor builtin_desc[] = { {(functionptr) builtin_displaymethodstart, "displaymethodstart"}, {(functionptr) builtin_displaymethodstop, "displaymethodstop"}, {(functionptr) builtin_monitorenter, "monitorenter"}, - {(functionptr) new_builtin_monitorenter, "monitorenter"}, + {(functionptr) asm_builtin_monitorenter, "monitorenter"}, {(functionptr) builtin_monitorexit, "monitorexit"}, - {(functionptr) new_builtin_monitorexit, "monitorexit"}, + {(functionptr) asm_builtin_monitorexit, "monitorexit"}, {(functionptr) builtin_idiv, "idiv"}, - {(functionptr) new_builtin_idiv, "idiv"}, + {(functionptr) asm_builtin_idiv, "idiv"}, {(functionptr) builtin_irem, "irem"}, - {(functionptr) new_builtin_irem, "irem"}, + {(functionptr) asm_builtin_irem, "irem"}, {(functionptr) builtin_ladd, "ladd"}, {(functionptr) builtin_lsub, "lsub"}, {(functionptr) builtin_lmul, "lmul"}, {(functionptr) builtin_ldiv, "ldiv"}, - {(functionptr) new_builtin_ldiv, "ldiv"}, + {(functionptr) asm_builtin_ldiv, "ldiv"}, {(functionptr) builtin_lrem, "lrem"}, - {(functionptr) new_builtin_lrem, "lrem"}, + {(functionptr) asm_builtin_lrem, "lrem"}, {(functionptr) builtin_lshl, "lshl"}, {(functionptr) builtin_lshr, "lshr"}, {(functionptr) builtin_lushr, "lushr"}, @@ -127,13 +123,12 @@ builtin_descriptor builtin_desc[] = { static s4 builtin_isanysubclass (classinfo *sub, classinfo *super) { - if (super->flags & ACC_INTERFACE) { - s4 index = super->index; - if (index >= sub->vftbl->interfacetablelength) return 0; - return ( sub->vftbl->interfacevftbl[index] ) ? 1 : 0; - } - return (sub->vftbl->lowclassval >= super->vftbl->lowclassval) & - (sub->vftbl->lowclassval <= super->vftbl->highclassval); + if (super->flags & ACC_INTERFACE) + return (sub->vftbl->interfacetablelength > super->index) && + (sub->vftbl->interfacetable[-super->index] != NULL); + + return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <= + (unsigned) (super->vftbl->diffval); } @@ -175,53 +170,19 @@ s4 builtin_checkcast(java_objectheader *obj, classinfo *class) log_text ("builtin_checkcast called"); #endif - if (!obj) return 1; - if ( builtin_isanysubclass (obj->vftbl->class, class) ) { + if (obj == NULL) return 1; - } -#if DEBUG - printf ("#### checkcast failed "); - unicode_display (obj->vftbl->class->name); - printf (" -> "); - unicode_display (class->name); - printf ("\n"); -#endif - - return 0; -} - - -/***************** function: builtin_checkclasscast **************************** - - Returns 1 (true) if the object "sub" is a subclass of the class "super", - otherwise returns 0 (false). If sub is NULL it also returns 1 (true). - -*******************************************************************************/ - -s4 builtin_checkclasscast(java_objectheader *sub, classinfo *super) -{ - if (!sub) + if (builtin_isanysubclass (obj->vftbl->class, class)) return 1; - return (sub->vftbl->lowclassval >= super->vftbl->lowclassval) & - (sub->vftbl->lowclassval <= super->vftbl->highclassval); -} - - -/***************** function: builtin_checkintercast **************************** - - Returns 1 (true) if the object "sub" is a subclass of the interface "super", - otherwise returns 0 (false). If "sub" is NULL it also returns 1 (true). - -*******************************************************************************/ - -s4 builtin_checkintercast(java_objectheader *sub, classinfo *super) -{ - if (!sub) - return 1; +#if DEBUG + printf ("#### checkcast failed "); + unicode_display (obj->vftbl->class->name); + printf (" -> "); + unicode_display (class->name); + printf ("\n"); +#endif - return (sub->vftbl->interfacetablelength > super->index) && - (sub->vftbl->interfacevftbl[super->index] != NULL); return 0; } @@ -1649,3 +1610,16 @@ float builtin_d2f (double a) } } + +/* + * These are local overrides for various environment variables in Emacs. + * Please do not remove this and leave it at the end of the file, where + * Emacs will automagically detect them. + * --------------------------------------------------------------------- + * Local variables: + * mode: c + * indent-tabs-mode: t + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ diff --git a/src/vm/builtin.h b/src/vm/builtin.h index 1343c63eb..9fcae7ddd 100644 --- a/src/vm/builtin.h +++ b/src/vm/builtin.h @@ -25,14 +25,11 @@ extern builtin_descriptor builtin_desc[]; s4 builtin_instanceof(java_objectheader *obj, classinfo *class); s4 builtin_checkcast(java_objectheader *obj, classinfo *class); -s4 new_builtin_checkcast(java_objectheader *obj, classinfo *class); -s4 new_builtin_checkclasscast(java_objectheader *obj, classinfo *class); -s4 new_builtin_checkintercast(java_objectheader *obj, classinfo *class); s4 builtin_arrayinstanceof (java_objectheader *obj, constant_arraydescriptor *desc); s4 builtin_checkarraycast (java_objectheader *obj, constant_arraydescriptor *desc); -s4 new_builtin_checkarraycast +s4 asm_builtin_checkarraycast (java_objectheader *obj, constant_arraydescriptor *desc); java_objectheader *builtin_throw_exception (java_objectheader *exception); @@ -60,7 +57,7 @@ java_arrayheader *builtin_nmultianewarray (int size, s4 builtin_canstore (java_objectarray *a, java_objectheader *o); s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o); -void new_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o); +void asm_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o); void builtin_trace_args(long a0, long a1, long a2, long a3, long a4, long a5, methodinfo *method); void builtin_displaymethodstart(methodinfo *method); @@ -69,22 +66,22 @@ void builtin_displaymethodstop(methodinfo *method, long l, double d); void builtin_displaymethodexception(methodinfo *method); void builtin_monitorenter (java_objectheader *o); -void new_builtin_monitorenter (java_objectheader *o); +void asm_builtin_monitorenter (java_objectheader *o); void builtin_monitorexit (java_objectheader *o); -void new_builtin_monitorexit (java_objectheader *o); +void asm_builtin_monitorexit (java_objectheader *o); s4 builtin_idiv (s4 a, s4 b); -s4 new_builtin_idiv (s4 a, s4 b); +s4 asm_builtin_idiv (s4 a, s4 b); s4 builtin_irem (s4 a, s4 b); -s4 new_builtin_irem (s4 a, s4 b); +s4 asm_builtin_irem (s4 a, s4 b); s8 builtin_ladd (s8 a, s8 b); s8 builtin_lsub (s8 a, s8 b); s8 builtin_lmul (s8 a, s8 b); s8 builtin_ldiv (s8 a, s8 b); -s8 new_builtin_ldiv (s8 a, s8 b); +s8 asm_builtin_ldiv (s8 a, s8 b); s8 builtin_lrem (s8 a, s8 b); -s8 new_builtin_lrem (s8 a, s8 b); +s8 asm_builtin_lrem (s8 a, s8 b); s8 builtin_lshl (s8 a, s4 b); s8 builtin_lshr (s8 a, s4 b); s8 builtin_lushr (s8 a, s4 b); diff --git a/src/vm/global.h b/src/vm/global.h index 8b7995c56..df11a012c 100644 --- a/src/vm/global.h +++ b/src/vm/global.h @@ -1,4 +1,4 @@ -/****************************** global.h *************************************** +/* global.h ******************************************************************** Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst @@ -7,10 +7,10 @@ Contains global definitions which are used in the whole program, includes some files and contains global used macros. - Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at - Changes: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at - Mark Probst EMAIL: cacao@complang.tuwien.ac.at - Philipp Tomsich EMAIL: cacao@complang.tuwien.ac.at + Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at + Andreas Krall (andi) EMAIL: cacao@complang.tuwien.ac.at + Changes: Mark Probst (schani) EMAIL: cacao@complang.tuwien.ac.at + Philipp Tomsich (phil) EMAIL: cacao@complang.tuwien.ac.at Last Change: 1998/10/30 @@ -25,7 +25,7 @@ marker functions on and off. */ #undef JIT_MARKER_SUPPORT /* phil */ -/***************************** standard includes ******************************/ +/* standard includes **********************************************************/ #include #include @@ -38,17 +38,16 @@ #include "toolbox/loging.h" -/**************************** system dependent types **************************/ +/* system dependent types *****************************************************/ #include "sysdep/types.h" -/**************************** additional data types ***************************/ +/* additional data types ******************************************************/ typedef void *voidptr; /* generic pointer */ - -typedef u1 bool; /* boolean data type */ +typedef int bool; /* boolean data type */ #define true 1 #define false 0 @@ -59,43 +58,42 @@ typedef void (*functionptr) (); /* generic function pointer */ #define MAX_ALIGN 8 /* most generic alignment for JavaVM values */ -/**************************** shutdown function *******************************/ +/* shutdown function **********************************************************/ void cacao_shutdown(s4 status); -/**************************** basic data types ********************************/ +/* basic data types ***********************************************************/ #define TYPE_INT 0 /* the JavaVM types must numbered in the */ #define TYPE_LONG 1 /* same order as the ICMD_Ixxx to ICMD_Axxx */ #define TYPE_FLOAT 2 /* instructions (LOAD and STORE) */ #define TYPE_DOUBLE 3 /* integer, long, float, double, address */ -#define TYPE_ADDRESS 4 /* all other types can be numbered arbitrarily*/ +#define TYPE_ADDRESS 4 /* all other types can be numbered arbitrarly */ #define TYPE_VOID 10 -/**************************** Java class file constants ***********************/ +/* Java class file constants **************************************************/ #define MAGIC 0xcafebabe #define MINOR_VERSION 3 #define MAJOR_VERSION 45 -#define CONSTANT_Class 7 -#define CONSTANT_Fieldref 9 -#define CONSTANT_Methodref 10 -#define CONSTANT_InterfaceMethodref 11 -#define CONSTANT_String 8 -#define CONSTANT_Integer 3 -#define CONSTANT_Float 4 -#define CONSTANT_Long 5 -#define CONSTANT_Double 6 -#define CONSTANT_NameAndType 12 -#define CONSTANT_Utf8 1 - -#define CONSTANT_Arraydescriptor 13 -#define CONSTANT_UNUSED 0 - +#define CONSTANT_Class 7 +#define CONSTANT_Fieldref 9 +#define CONSTANT_Methodref 10 +#define CONSTANT_InterfaceMethodref 11 +#define CONSTANT_String 8 +#define CONSTANT_Integer 3 +#define CONSTANT_Float 4 +#define CONSTANT_Long 5 +#define CONSTANT_Double 6 +#define CONSTANT_NameAndType 12 +#define CONSTANT_Utf8 1 + +#define CONSTANT_Arraydescriptor 13 +#define CONSTANT_UNUSED 0 #define ACC_PUBLIC 0x0001 #define ACC_PRIVATE 0x0002 @@ -110,67 +108,90 @@ void cacao_shutdown(s4 status); #define ACC_ABSTRACT 0x0400 - -/**************************** resolve typedef-cycles **************************/ +/* resolve typedef cycles *****************************************************/ typedef struct unicode unicode; +typedef struct java_objectheader java_objectheader; typedef struct classinfo classinfo; typedef struct vftbl vftbl; typedef u1* methodptr; -/********************** data structures of UNICODE symbol *********************/ +/* constant pool entries ******************************************************* -struct unicode { - unicode *hashlink; /* externe Verkettung f"ur die unicode-Hashtabelle */ - u4 key; /* Hash-Schl"ussel (h"angt nur vom Text ab) */ - int length; /* L"ange des Textes */ - u2 *text; /* Zeiger auf den Text (jeder Buchstabe 16 Bit) */ - classinfo *class; /* gegebenenfalls Referenz auf die Klasse dieses - Namens (oder NULL, wenn es keine solche gibt) */ - struct java_objectheader *string; - /* gegebenenfalls Referenz auf einen konstanten - String mit dem entsprechenden Wert */ -}; + All constant pool entries need a data structure which contain the entrys + value. In some cases this structure exist already, in the remaining cases + this structure must be generated: -/* Alle Unicode-Symbole werden in einer einzigen globalen Tabelle - (Hashtabelle) verwaltet, jedes Symbol wird nur einmal angelegt. - -> Speicherersparnis, und "Uberpr"ufung auf Gleichheit durch einfachen - Zeigervergleich */ + kind structure generated? + ---------------------------------------------------------------------- + CONSTANT_Class classinfo no + CONSTANT_Fieldref constant_FMIref yes + CONSTANT_Methodref constant_FMIref yes + CONSTANT_InterfaceMethodref constant_FMIref yes + CONSTANT_String unicode no + CONSTANT_Integer constant_integer yes + CONSTANT_Float constant_float yes + CONSTANT_Long constant_long yes + CONSTANT_Double constant_double yes + CONSTANT_NameAndType constant_nameandtype yes + CONSTANT_Utf8 unicode no + CONSTANT_Arraydescriptor constant_arraydescriptor yes + CONSTANT_UNUSED - +*******************************************************************************/ -/************ data structures of remaining constant pool entries **************/ +/* data structures of Unicode symbol ******************************************* + All Unicode symbols are stored in one global (hash) table, every symbol + exists only once. Equal symbols have identical pointers. +*/ + +struct unicode { + unicode *hashlink; /* link for external hash chain */ + u4 key; /* hash key (computed from text) */ + int length; /* text length */ + u2 *text; /* pointer to text (each character is 16 Bit) */ + classinfo *class; /* class pointer if it exists, otherwise NULL */ + java_objectheader *string; /* string pointer if it exists, otherwise NULL*/ +}; -typedef struct { - classinfo *class; - unicode *name; - unicode *descriptor; -} constant_FMIref; +/* data structures of remaining constant pool entries *************************/ -typedef struct { +typedef struct { /* Fieldref, Methodref and InterfaceMethodref */ + classinfo *class; /* class containing this field/method/interface */ + unicode *name; /* field/method/interface name */ + unicode *descriptor; /* field/method/interface type descriptor string */ +} constant_FMIref; + +typedef struct { /* Integer */ s4 value; } constant_integer; -typedef struct { +typedef struct { /* Float */ float value; } constant_float; -typedef struct { +typedef struct { /* Long */ s8 value; } constant_long; -typedef struct { +typedef struct { /* Double */ double value; } constant_double; - -typedef struct { - unicode *name; - unicode *descriptor; +typedef struct { /* NameAndType (Field or Method) */ + unicode *name; /* field/method name */ + unicode *descriptor; /* field/method type descriptor string */ } constant_nameandtype; +/* arraydescriptor describes array types. Basic array types contain their + type in the arraytype field, objectclass contains a class pointer for + arrays of objects (arraytype == ARRAYTYPE_OBJECT), elementdescriptor + contains a pointer to an arraydescriptor which describes the element + types in the case of arrays of arrays (arraytype == ARRAYTYPE_ARRAY). +*/ typedef struct constant_arraydescriptor { int arraytype; @@ -178,75 +199,28 @@ typedef struct constant_arraydescriptor { struct constant_arraydescriptor *elementdescriptor; } constant_arraydescriptor; -/* Mit einem Arraydescriptor kann ein Array-Typ dargestellt werden. - Bei normalen Arrays (z.B. Array von Bytes,...) gen"ugt dazu, - dass das Feld arraytype die entsprechende Kennzahl enth"alt - (z.B. ARRAYTYPE_BYTE). - Bei Arrays von Objekten (arraytype=ARRAYTYPE_OBJECT) muss das - Feld objectclass auf die Klassenstruktur der m"oglichen - Element-Objekte zeigen. - Bei Arrays von Arrays (arraytype=ARRAYTYPE_ARRAY) muss das - Feld elementdescriptor auf eine weiter arraydescriptor-Struktur - zeigen, die die Element-Typen beschreibt. - */ - - - -/********* Anmerkungen zum Constant-Pool: - - Die Typen der Eintr"age in den Constant-Pool werden durch die oben - definierten CONSTANT_.. Werte angegeben. - Bei allen Typen muss zus"atzlich noch eine Datenstruktur hinzugef"ugt - werden, die den wirklichen Wert angibt. - Bei manchen Typen reicht es, einen Verweis auf eine schon bereits - existierende Struktur (z.B. unicode-Texte) einzutragen, bei anderen - muss diese Struktur erst extra erzeugt werden. - Ich habe folgende Datenstrukturen f"ur diese Typen verwendet: - - Typ Struktur extra erzeugt? - ---------------------------------------------------------------------- - CONSTANT_Class classinfo nein - CONSTANT_Fieldref constant_FMIref ja - CONSTANT_Methodref constant_FMIref ja - CONSTANT_InterfaceMethodref constant_FMIref ja - CONSTANT_String unicode nein - CONSTANT_Integer constant_integer ja - CONSTANT_Float constant_float ja - CONSTANT_Long constant_long ja - CONSTANT_Double constant_double ja - CONSTANT_NameAndType constant_nameandtype ja - CONSTANT_Utf8 unicode nein - CONSTANT_Arraydescriptor constant_arraydescriptor ja - CONSTANT_UNUSED - - -*******************************/ - +/* data structures of the runtime system **************************************/ -/***************** Die Datenstrukturen fuer das Laufzeitsystem ****************/ +/* objects ********************************************************************* + All objects (and arrays) which resides on the heap need the following + header at the beginning of the data structure. +*/ - /********* Objekte ********** - - Alle Objekte (und Arrays), die am Heap gespeichert werden, m"ussen eine - folgende spezielle Datenstruktur ganz vorne stehen haben: - - */ +struct java_objectheader { /* header for all objects */ + vftbl *vftbl; /* pointer to virtual function table */ +}; -typedef struct java_objectheader { /* Der Header f"ur alle Objekte */ - vftbl *vftbl; /* Zeiger auf die Function Table */ -} java_objectheader; +/* arrays ********************************************************************** -/********* Arrays *********** - - Alle Arrays in Java sind auch gleichzeitig Objekte (d.h. sie haben auch - den obligatorischen Object-Header und darin einen Verweis auf eine Klasse) - Es gibt aber (der Einfachheit halber) nur eine einzige Klasse f"ur alle - m"oglichen Typen von Arrays, deshalb wird der tats"achliche Typ in einem - Feld im Array-Objekt selbst gespeichert. - Die Typen sind: */ + All arrays are objects (they need the object header with a pointer to a + vvftbl (array class table). There is only one class for all arrays. The + type of an array is stored directly in the array object. Following types + are defined: +*/ #define ARRAYTYPE_INT 0 #define ARRAYTYPE_LONG 1 @@ -259,18 +233,15 @@ typedef struct java_objectheader { /* Der Header f"ur alle Objekte */ #define ARRAYTYPE_OBJECT 8 #define ARRAYTYPE_ARRAY 9 - -/** Der Header f"ur ein Java-Array **/ - -typedef struct java_arrayheader { /* Der Arrayheader f"ur alle Arrays */ - java_objectheader objheader; /* Der Object-Header */ - s4 size; /* Gr"osse des Arrays */ - s4 arraytype; /* Typ der Elemente */ +typedef struct java_arrayheader { /* header for all arrays */ + java_objectheader objheader; /* object header */ + s4 size; /* array size */ + s4 arraytype; /* array type from previous list */ } java_arrayheader; -/** Die Unterschiedlichen Strukturen f"ur alle Typen von Arrays **/ +/* structs for all kinds of arrays ********************************************/ typedef struct java_chararray { java_arrayheader header; @@ -287,10 +258,8 @@ typedef struct java_doublearray { double data[1]; } java_doublearray; - -/* achtung: die beiden Stukturen booleanarray und bytearray m"ussen - identisches memory-layout haben, weil mit den selben Funktionen - darauf zugegriffen wird */ +/* booleanarray and bytearray need identical memory layout (access methods + use the same machine code */ typedef struct java_booleanarray { java_arrayheader header; @@ -317,10 +286,8 @@ typedef struct java_longarray { s8 data[1]; } java_longarray; - -/* ACHTUNG: die beiden folgenden Strukturen m"ussen unbedingt gleiches - Memory-Layout haben, weil mit ein und der selben Funktion auf die - data-Eintr"age beider Typen zugegriffen wird !!!! */ +/* objectarray and arrayarray need identical memory layout (access methods + use the same machine code */ typedef struct java_objectarray { java_arrayheader header; @@ -335,12 +302,9 @@ typedef struct java_arrayarray { } java_arrayarray; +/* field, method and class structures *****************************************/ - -/******************** class, field and method structures **********************/ - - -/********************** structure: fieldinfo **********************************/ +/* fieldinfo ******************************************************************/ typedef struct fieldinfo {/* field of a class */ s4 flags; /* ACC flags */ @@ -361,7 +325,7 @@ typedef struct fieldinfo {/* field of a class */ } fieldinfo; -/********************** structure: exceptiontable *****************************/ +/* exceptiontable *************************************************************/ typedef struct exceptiontable { /* exceptiontable entry in a method */ s4 startpc; /* start pc of guarded area (inclusive) */ @@ -371,7 +335,7 @@ typedef struct exceptiontable { /* exceptiontable entry in a method */ } exceptiontable; -/********************** structure: methodinfo *********************************/ +/* methodinfo *****************************************************************/ typedef struct methodinfo { /* method structure */ s4 flags; /* ACC flags */ @@ -381,25 +345,25 @@ typedef struct methodinfo { /* method structure */ s4 paramcount; /* only temporary valid, parameter count */ u1 *paramtypes; /* only temporary valid, parameter types */ classinfo *class; /* class, the method belongs to */ - u4 vftblindex; /* index of method in virtual function table + s4 vftblindex; /* index of method in virtual function table (if it is a virtual method) */ s4 maxstack; /* maximum stack depth of method */ s4 maxlocals; /* maximum number of local variables */ - u4 jcodelength; /* length of JavaVM code */ + s4 jcodelength; /* length of JavaVM code */ u1 *jcode; /* pointer to JavaVM code */ s4 exceptiontablelength;/* exceptiontable length */ exceptiontable *exceptiontable; /* the exceptiontable */ u1 *stubroutine; /* stub for compiling or calling natives */ - u4 mcodelength; /* legth of generated machine code */ + s4 mcodelength; /* legth of generated machine code */ u1 *mcode; /* pointer to machine code */ u1 *entrypoint; /* entry point in machine code */ } methodinfo; -/********************** structure: classinfo **********************************/ +/* classinfo ******************************************************************/ struct classinfo { /* class structure */ java_objectheader header; /* classes are also objects */ @@ -439,66 +403,84 @@ struct classinfo { /* class structure */ methodinfo *marker; #endif }; + + +/* virtual function table ****************************************************** + + The vtbl has a bidirectional layout with open ends at both sides. + interfacetablelength gives the number of entries of the interface table at + the start of the vftbl. The vftbl pointer points to &interfacetable[0]. + vftbllength gives the number of entries of table at the end of the vftbl. + + runtime type check (checkcast): + + Different methods are used for runtime type check depending on the + argument of checkcast/instanceof. + A check against a class is implemented via relative numbering on the class + hierachy tree. The tree is numbered in a depth first traversal setting + the base field and the diff field. The diff field gets the result of + (high - base) so that a range check can be implemented by an unsigned + compare. A sub type test is done by checking the inclusion of base of + the sub class in the range of the superclass. + + A check against an interface is implemented via the interfacevftbl. If the + interfacevftbl contains a nonnull value a class is a subclass of this + interface. + + interfacetable: + + Like standard virtual methods interface methods are called using + virtual function tables. All interfaces are numbered sequentially + (starting with zero). For each class there exist an interface table + of virtual function tables for each implemented interface. The length + of the interface table is determined by the highest number of an + implemented interface. + + The following example assumes a class which implements interface 0 and 3: + + interfacetablelength = 4 + + | ... | +----------+ + +-----------+ | method 2 |---> method z + | class | | method 1 |---> method y + +-----------+ | method 0 |---> method x + | ivftbl 0 |----------> +----------+ + vftblptr ---> +-----------+ + | ivftbl -1 |--> NULL +----------+ + | ivftbl -2 |--> NULL | method 1 |---> method x + | ivftbl -3 |-----+ | method 0 |---> method a + +-----------+ +----> +----------+ + + +---------------+ + | length 3 = 2 | + | length 2 = 0 | + | length 1 = 0 | + | length 0 = 3 | + interfacevftbllength ---> +---------------+ + +*******************************************************************************/ struct vftbl { - classinfo *class; /* Class, the function table belongs to */ + methodptr *interfacetable[1]; /* interface table (access via macro) */ + + classinfo *class; /* class, the vtbl belongs to */ - s4 vftbllength; /* virtual function table length */ - s4 interfacetablelength; /* interface table length */ + s4 vftbllength; /* virtual function table length */ + s4 interfacetablelength; /* interface table length */ - s4 lowclassval; /* low value for relative numbering */ - s4 highclassval; /* high value for relative numbering */ + s4 baseval; /* base for runtime type check */ + s4 diffval; /* high - base for runtime type check */ - u4 *interfacevftbllength; /* see description below */ - methodptr **interfacevftbl; + s4 *interfacevftbllength; /* length of interface vftbls */ - methodptr table[1]; + methodptr table[1]; /* class vftbl */ }; -/*********** Anmerkungen zur Interfacetable: - - "Ahnlich wie die 'normalen' virtuellen Methoden k"onnen auch die - Interface-Methoden mit Hilfe einer Art Virtual Function Table - aufgerufen werden. - Dazu werden alle Interfaces im System fortlaufend nummeriert (beginnend - bei 0), und f"ur jede Klasse wird eine ganze Tabelle von - Virtual Function Tables erzeugt, n"amlich zu jedem Interface, das die - Klasse implementiert, eine. - - z.B. Nehmen wir an, eine Klasse implementiert zwei Interfaces (die durch - die Nummerierung die Indizes 0 und 3 bekommen haben) - - Das sieht dann ungef"ahr so aus: - -------------- ------------- - interfacevftbl ---> | Eintrag 0 |---------> | Methode 0 |---> Methode X - | Eintrag 1 |--> NULL | Methode 1 |---> Methode Y - | Eintrag 2 |--> NULL | Methode 2 |---> Methode Z - | Eintrag 3 |-----+ ------------- - -------------- | - +---> ------------- - | Methode 0 |---> Methode X - | Methode 1 |---> Methode A - ------------- - --------------- - interfacevftlblength ---> | Wert 0 = 3 | - | Wert 1 = 0 | - | Wert 2 = 0 | - | Wert 3 = 2 | - --------------- - - Der Aufruf einer Interface-Methode geht dann so vor sich: - Zur Compilezeit steht der Index (i) des Interfaces und die Stelle (s), wo - in der entsprechenden Untertabelle die Methode eingetragen ist, schon fest. - Also muss zur Laufzeit nur mehr der n-te Eintrag aus der Interfacetable - gelesen werden, von dieser Tabelle aus wird der s-te Eintrag geholt, - und diese Methode wird angesprungen. - -****************/ - - - -/********************** references to some system classes ********************/ +#define VFTBLINTERFACETABLE(v,i) (v)->interfacetable[-i] + + +/* references to some system classes ******************************************/ extern classinfo *class_java_lang_Object; extern classinfo *class_java_lang_String; @@ -514,7 +496,7 @@ extern classinfo *class_java_lang_ThreadDeath; extern classinfo *class_array; -/********************** instances of some system classes **********************/ +/* instances of some system classes *******************************************/ extern java_objectheader *proto_java_lang_ClassCastException; extern java_objectheader *proto_java_lang_NullPointerException; @@ -526,14 +508,14 @@ extern java_objectheader *proto_java_lang_ArrayStoreException; extern java_objectheader *proto_java_lang_ThreadDeath; -/******************************* flag variables *******************************/ +/* flag variables *************************************************************/ extern bool compileall; extern bool runverbose; extern bool verbose; -/******************************* trace variables ******************************/ +/* statistic variables ********************************************************/ extern int count_class_infos; extern int count_const_pool_len; diff --git a/src/vm/loader.c b/src/vm/loader.c index 38324b031..3927e3a7c 100644 --- a/src/vm/loader.c +++ b/src/vm/loader.c @@ -1,5 +1,4 @@ -/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */ -/****************************** loader.c *************************************** +/* loader.c ******************************************************************** Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst @@ -29,18 +28,18 @@ #include "threads/thread.h" /* schani */ -/*************************** globale Variablen *******************************/ +/* global variables ***********************************************************/ -extern bool newcompiler; +extern bool newcompiler; /* true if new compiler is used */ -int count_class_infos = 0; +int count_class_infos = 0; /* variables for measurements */ int count_const_pool_len = 0; int count_vftbl_len = 0; int count_all_methods = 0; int count_vmcode_len = 0; int count_extable_len = 0; -bool loadverbose = false; /* Switches f"ur mehr Debug-Meldungen */ +bool loadverbose = false; /* switches for debug messages */ bool linkverbose = false; bool initverbose = false; @@ -50,17 +49,15 @@ bool getloadingtime = false; long int loadingtime = 0; -static u4 interfaceindex; /* fortlaufende Nummer f"ur Interfaces */ +static s4 interfaceindex; /* sequential numbering of interfaces */ -static list unloadedclasses; /* Liste alle referenzierten, aber noch nicht - geladenen Klassen */ -static list unlinkedclasses; /* Liste aller geladenen, aber noch nicht - gelinkten Klassen */ - list linkedclasses; /* Liste aller fertig gelinkten Klassen */ +static list unloadedclasses; /* list of all referenced but not loaded classes */ +static list unlinkedclasses; /* list of all loaded but not linked classes */ + list linkedclasses; /* list of all completely linked classes */ -/***************** die Referenzen auf die wichtigen Systemklassen ************/ +/* important system classes ***************************************************/ classinfo *class_java_lang_Object; classinfo *class_java_lang_String; @@ -76,7 +73,7 @@ classinfo *class_java_lang_ThreadDeath; /* schani */ classinfo *class_array; -/************ einige vorgefertigte Instanzen wichtiger Systemklassen *********/ +/* instances of important system classes **************************************/ java_objectheader *proto_java_lang_ClassCastException; java_objectheader *proto_java_lang_NullPointerException; @@ -90,12 +87,12 @@ java_objectheader *proto_java_lang_ThreadDeath; /* schani */ -/****************************************************************************/ -/******************* Einige Support-Funkionen *******************************/ -/****************************************************************************/ +/******************************************************************************/ +/******************* Einige Support-Funkionen *********************************/ +/******************************************************************************/ -/********** interne Funktion: printflags (nur zu Debug-Zwecken) ************/ +/********** interne Funktion: printflags (nur zu Debug-Zwecken) **************/ static void printflags (u2 f) { @@ -113,56 +110,53 @@ static void printflags (u2 f) } -/************************* Funktion: skipattribute **************************** +/************************* Funktion: skipattribute ***************************** "uberliest im ClassFile eine (1) 'attribute'-Struktur -******************************************************************************/ +*******************************************************************************/ static void skipattribute () { - u4 len; - suck_u2 (); - len = suck_u4 (); - skip_nbytes (len); + skip_nbytes(suck_u4()); } -/********************** Funktion: skipattributebody *************************** +/********************** Funktion: skipattributebody **************************** "uberliest im Classfile ein attribut, wobei die 16-bit - attribute_name - Referenz schon gelesen worden ist. -******************************************************************************/ +*******************************************************************************/ static void skipattributebody () { - u4 len = suck_u4 (); - skip_nbytes (len); + skip_nbytes(suck_u4()); } -/************************* Funktion: skipattributes *************************** +/************************* Funktion: skipattributes **************************** "uberliest im ClassFile eine gew"unschte Anzahl von attribute-Strukturen -******************************************************************************/ +*******************************************************************************/ static void skipattributes (u4 num) { u4 i; - for (i=0; i linked = false; c -> index = 0; c -> instancesize = 0; + c -> header.vftbl = NULL; c -> vftbl = NULL; c -> initialized = false; @@ -717,12 +712,12 @@ classinfo *class_get (unicode *u) -/******************** Funktion: class_getconstant ***************************** +/******************** Funktion: class_getconstant ****************************** holt aus dem ConstantPool einer Klasse den Wert an der Stelle 'pos'. Der Wert mu"s vom Typ 'ctype' sein, sonst wird das System angehalten. -******************************************************************************/ +*******************************************************************************/ voidptr class_getconstant (classinfo *c, u4 pos, u4 ctype) { @@ -738,12 +733,12 @@ voidptr class_getconstant (classinfo *c, u4 pos, u4 ctype) } -/********************* Funktion: class_constanttype *************************** +/********************* Funktion: class_constanttype **************************** Findet heraus, welchen Typ ein Eintrag in den ConstantPool einer Klasse hat. -******************************************************************************/ +*******************************************************************************/ u4 class_constanttype (classinfo *c, u4 pos) { @@ -753,7 +748,7 @@ u4 class_constanttype (classinfo *c, u4 pos) } -/******************** Funktion: class_loadcpool ******************************* +/******************** Funktion: class_loadcpool ******************************** l"adt den gesammten ConstantPool einer Klasse. @@ -761,7 +756,7 @@ u4 class_constanttype (classinfo *c, u4 pos) Format gebracht (Klassenreferenzen werden aufgel"ost, ...) F"ur eine genaue "Ubersicht "uber das kompakte Format siehe: 'global.h' -******************************************************************************/ +*******************************************************************************/ static void class_loadcpool (classinfo *c) { @@ -1050,7 +1045,7 @@ static void class_loadcpool (classinfo *c) } -/********************** Funktion: class_load ********************************** +/********************** Funktion: class_load *********************************** l"adt alle Infos f"ur eine ganze Klasse aus einem ClassFile. Die 'classinfo'-Struktur mu"s bereits angelegt worden sein. @@ -1062,7 +1057,7 @@ static void class_loadcpool (classinfo *c) Die gelesene Klasse wird dann aus der Liste 'unloadedclasses' ausgetragen und in die Liste 'unlinkedclasses' eingh"angt. -******************************************************************************/ +*******************************************************************************/ static void class_load (classinfo *c) { @@ -1142,12 +1137,12 @@ static void class_load (classinfo *c) -/************** interne Funktion: class_highestinterface ********************** +/************** interne Funktion: class_highestinterface *********************** wird von der Funktion class_link ben"otigt, um festzustellen, wie gro"s die Interfacetable einer Klasse sein mu"s. -******************************************************************************/ +*******************************************************************************/ static s4 class_highestinterface (classinfo *c) { @@ -1169,46 +1164,47 @@ static s4 class_highestinterface (classinfo *c) } -/**************** Funktion: class_addinterface ******************************** +/* class_addinterface ********************************************************** wird von der Funktion class_link ben"otigt, um eine Virtual Function Table f"ur ein Interface (und alle weiteren von diesem Interface implementierten Interfaces) in eine Klasse einzutragen. -******************************************************************************/ +*******************************************************************************/ static void class_addinterface (classinfo *c, classinfo *ic) { - u4 i = ic->index; - u4 j,m; + s4 j, m; + s4 i = ic->index; vftbl *vftbl = c->vftbl; - if (i>=vftbl->interfacetablelength) panic ("Interfacetable-Overflow"); - if (vftbl->interfacevftbl[i]) return; + if (i >= vftbl->interfacetablelength) + panic ("Inernal error: interfacetable overflow"); + if (vftbl->interfacetable[-i]) + return; - if (ic->methodscount==0) { /* wenn interface keine Methoden hat, dann - trotzdem eine Tabelle mit L"ange 1 anlegen, - wegen Subclass-Tests */ - vftbl -> interfacevftbllength[i] = 1; - vftbl -> interfacevftbl[i] = MNEW(methodptr, 1); - vftbl -> interfacevftbl[i][0] = NULL; + if (ic->methodscount == 0) { /* fake entry needed for subtype test */ + vftbl->interfacevftbllength[i] = 1; + vftbl->interfacetable[-i] = MNEW(methodptr, 1); + vftbl->interfacetable[-i][0] = NULL; } else { - vftbl -> interfacevftbllength[i] = ic -> methodscount; - vftbl -> interfacevftbl[i] = MNEW(methodptr, ic -> methodscount); + vftbl->interfacevftbllength[i] = ic->methodscount; + vftbl->interfacetable[-i] = MNEW(methodptr, ic->methodscount); #ifdef STATISTICS - count_vftbl_len += sizeof(methodptr) * ic -> methodscount; + count_vftbl_len += sizeof(methodptr) * + (ic->methodscount + (ic->methodscount == 0)); #endif for (j=0; jmethodscount; j++) { classinfo *sc = c; while (sc) { - for (m=0; mmethodscount; m++) { + for (m = 0; m < sc->methodscount; m++) { methodinfo *mi = &(sc->methods[m]); - if (method_canoverwrite (mi, &(ic->methods[j])) ) { - vftbl->interfacevftbl[i][j] = - vftbl->table[mi->vftblindex]; + if (method_canoverwrite(mi, &(ic->methods[j]))) { + vftbl->interfacetable[-i][j] = + vftbl->table[mi->vftblindex]; goto foundmethod; } } @@ -1217,13 +1213,13 @@ static void class_addinterface (classinfo *c, classinfo *ic) foundmethod: ; } } - - for (j=0; jinterfacescount; j++) + + for (j = 0; j < ic->interfacescount; j++) class_addinterface(c, ic->interfaces[j]); } -/********************** Funktion: class_link ********************************** +/********************** Funktion: class_link *********************************** versucht, eine Klasse in das System voll zu integrieren (linken). Dazu m"ussen sowol die Superklasse, als auch alle implementierten @@ -1240,53 +1236,60 @@ static void class_addinterface (classinfo *c, classinfo *ic) Achtung: Bei zyklischen Klassendefinitionen ger"at das Programm hier in eine Endlosschleife!! (Da muss ich mir noch was einfallen lassen) -******************************************************************************/ +*******************************************************************************/ static void class_link (classinfo *c) { - u4 supervftbllength; /* L"ange der VFTBL der Superklasse */ - u4 vftbllength; /* L"ange der VFTBL dieser Klasse */ - classinfo *super = c->super; - classinfo *ic,*c2; /* Hilfsvariablen */ - vftbl *v; - u4 i; + s4 supervftbllength; /* vftbllegnth of super class */ + s4 vftbllength; /* vftbllength of current class */ + s4 interfacetablelength; /* interface table length */ + classinfo *super = c->super; /* super class */ + classinfo *ic, *c2; /* intermediate class variables */ + vftbl *v; /* vftbl of current class */ + s4 i; /* interface/method/field counter */ - /* schauen, ob alle "ubergeordneten Klassen schon fertig sind, - und richtiges Initialisieren der lokalen Variablen */ + /* check if all superclasses are already linked, if not put c at end of + unlinked list and return. Additionally initialize class fields. */ - for ( i=0; iinterfacescount; i++) { + /* check interfaces */ + + for (i = 0; i < c->interfacescount; i++) { ic = c->interfaces[i]; - if ( !ic -> linked) { - list_remove (&unlinkedclasses,c ); - list_addlast (&unlinkedclasses,c ); + if (!ic->linked) { + list_remove(&unlinkedclasses, c); + list_addlast(&unlinkedclasses, c); return; } } - if (! super) { - c -> index = 0; - c -> instancesize = sizeof (java_objectheader); + /* check super class */ + + if (super == NULL) { /* class java.long.Object */ + c->index = 0; + c->instancesize = sizeof(java_objectheader); vftbllength = supervftbllength = 0; - c -> finalizer = NULL; + c->finalizer = NULL; } else { - if ( !super -> linked ) { - list_remove (&unlinkedclasses,c ); - list_addlast (&unlinkedclasses,c ); + if (!super->linked) { + list_remove(&unlinkedclasses, c); + list_addlast(&unlinkedclasses, c); return; } - if ( c->flags & ACC_INTERFACE) c -> index = interfaceindex++; - else c -> index = super -> index + 1; + if (c->flags & ACC_INTERFACE) + c->index = interfaceindex++; + else + c->index = super->index + 1; - c -> instancesize = super -> instancesize; + c->instancesize = super->instancesize; - vftbllength = supervftbllength = super -> vftbl -> vftbllength; + vftbllength = supervftbllength = super->vftbl->vftbllength; - c -> finalizer = super -> finalizer; + c->finalizer = super->finalizer; } @@ -1296,25 +1299,25 @@ static void class_link (classinfo *c) dolog (); } - /* Erstellen der Virtual Function Table */ + /* compute vftbl length */ - for (i=0; i < c->methodscount; i++) { + for (i = 0; i < c->methodscount; i++) { methodinfo *m = &(c->methods[i]); - if (! (m->flags & ACC_STATIC) ) { + if (!(m->flags & ACC_STATIC)) { /* is instance method */ classinfo *sc = super; while (sc) { int j; - for (j=0; j < sc->methodscount; j++) { - if ( method_canoverwrite (m, &(sc->methods[j])) ) { - m -> vftblindex = sc->methods[j].vftblindex; + for (j = 0; j < sc->methodscount; j++) { + if (method_canoverwrite(m, &(sc->methods[j]))) { + m->vftblindex = sc->methods[j].vftblindex; goto foundvftblindex; } } sc = sc->super; } - m -> vftblindex = (vftbllength++); - foundvftblindex: ; + m->vftblindex = (vftbllength++); +foundvftblindex: ; } } @@ -1322,106 +1325,114 @@ static void class_link (classinfo *c) count_vftbl_len += sizeof(vftbl) + sizeof(methodptr)*(vftbllength-1); #endif - c -> vftbl = v = (vftbl*) - mem_alloc (sizeof(vftbl) + sizeof(methodptr)*(vftbllength-1)); - v -> class = c; - v -> vftbllength = vftbllength; - v -> interfacetablelength = 0; - - for (i=0; i < supervftbllength; i++) - v -> table[i] = super -> vftbl -> table[i]; + /* compute interfacetable length */ + + interfacetablelength = 0; + c2 = c; + while (c2) { + for (i = 0; i < c2->interfacescount; i++) { + s4 h = class_highestinterface (c2->interfaces[i]) + 1; + if (h > interfacetablelength) + interfacetablelength = h; + } + c2 = c2->super; + } + + /* allocate virtual function table */ + + v = (vftbl*) mem_alloc(sizeof(vftbl) + sizeof(methodptr) * + (vftbllength - 1) + sizeof(methodptr*) * + (interfacetablelength - (interfacetablelength > 0))); + v = (vftbl*) (((methodptr*) v) + (interfacetablelength - 1) * + (interfacetablelength > 1)); + c->header.vftbl = c->vftbl = v; + v->class = c; + v->vftbllength = vftbllength; + v->interfacetablelength = interfacetablelength; + + /* copy virtual function table of super class */ + + for (i = 0; i < supervftbllength; i++) + v->table[i] = super->vftbl->table[i]; - for (i=0; i < c->methodscount; i++) { + /* add method stubs into virtual function table */ + + for (i = 0; i < c->methodscount; i++) { methodinfo *m = &(c->methods[i]); - if ( ! (m->flags & ACC_STATIC) ) { - v -> table[m->vftblindex] = m -> stubroutine; + if (!(m->flags & ACC_STATIC)) { + v->table[m->vftblindex] = m->stubroutine; } } - - /* Berechnen der Instanzengr"o"se und der Offsets der einzelnen - Felder */ + /* compute instance size and offset of each field */ - for (i=0; i < c->fieldscount; i++) { - u4 dsize; - fieldinfo *f = &(c -> fields[i]); + for (i = 0; i < c->fieldscount; i++) { + s4 dsize; + fieldinfo *f = &(c->fields[i]); - if ( ! (f->flags & ACC_STATIC) ) { + if (!(f->flags & ACC_STATIC) ) { dsize = desc_typesize (f->descriptor); - c -> instancesize = ALIGN ( c->instancesize, dsize); - f -> offset = c -> instancesize; - c -> instancesize += dsize; + c->instancesize = ALIGN (c->instancesize, dsize); + f->offset = c->instancesize; + c->instancesize += dsize; } - } + /* initialize interfacetable and interfacevftbllength */ - /* Berechnen der Virtual Function Tables f"ur alle Interfaces */ - - c2 = c; - while (c2) { - for (i=0; iinterfacescount; i++) { - s4 h = class_highestinterface (c2->interfaces[i]) + 1; - if ( h > v->interfacetablelength) v->interfacetablelength = h; - } - c2 = c2->super; - } - v -> interfacevftbllength = MNEW (u4, v->interfacetablelength); - v -> interfacevftbl = MNEW (methodptr *, v->interfacetablelength); + v->interfacevftbllength = MNEW (s4, interfacetablelength); #ifdef STATISTICS - count_vftbl_len += (4 + sizeof(methodptr*)) * v->interfacetablelength; + count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength; #endif - for (i=0; i < v->interfacetablelength; i++) { - v -> interfacevftbllength[i] = 0; - v -> interfacevftbl[i] = NULL; + for (i = 0; i < interfacetablelength; i++) { + v->interfacevftbllength[i] = 0; + v->interfacetable[-i] = NULL; } - c2 = c; - while (c2) { - for (i=0; iinterfacescount; i++) { + /* add interfaces */ + + for (c2 = c; c2 != NULL; c2 = c2->super) + for (i = 0; i < c2->interfacescount; i++) { class_addinterface (c, c2->interfaces[i]); } - c2 = c2->super; - } - - - /* Die finalizer-Methode suchen und eintragen (wenn vorhanden), - aber nur bei Objekten ausser java.lang.Object */ + /* add finalizer method (not for java.lang.Object) */ - if (super) { + if (super != NULL) { methodinfo *fi; - static unicode *finame=NULL,*fidesc=NULL; - - if (!finame) finame = unicode_new_char ("finalize"); - if (!fidesc) fidesc = unicode_new_char ("()V"); + static unicode *finame = NULL; + static unicode *fidesc = NULL; + + if (finame == NULL) + finame = unicode_new_char("finalize"); + if (fidesc == NULL) + fidesc = unicode_new_char("()V"); fi = class_findmethod (c, finame, fidesc); - if (fi) { - if (! (fi->flags & ACC_STATIC) ) { - c -> finalizer = fi; + if (fi != NULL) { + if (!(fi->flags & ACC_STATIC)) { + c->finalizer = fi; } } - } - - - /* Abschlie"sende Aktionen */ - - c -> linked = true; + } + + /* final tasks */ + + c->linked = true; list_remove (&unlinkedclasses, c); list_addlast (&linkedclasses, c); } -/******************* Funktion: class_freepool ********************************* +/******************* Funktion: class_freepool ********************************** Gibt alle Resourcen, die der ConstantPool einer Klasse ben"otigt, wieder frei. -******************************************************************************/ +*******************************************************************************/ static void class_freecpool (classinfo *c) { @@ -1467,15 +1478,15 @@ static void class_freecpool (classinfo *c) } -/*********************** Funktion: class_free ********************************* +/*********************** Funktion: class_free ********************************** Gibt alle Resourcen, die eine ganze Klasse ben"otigt, frei -******************************************************************************/ +*******************************************************************************/ static void class_free (classinfo *c) { - u4 i; + s4 i; vftbl *v; unicode_unlinkclass (c->name); @@ -1484,38 +1495,44 @@ static void class_free (classinfo *c) MFREE (c->interfaces, classinfo*, c->interfacescount); - for (i=0; i < c->fieldscount; i++) field_free ( &(c->fields[i]) ); + for (i = 0; i < c->fieldscount; i++) + field_free(&(c->fields[i])); MFREE (c->fields, fieldinfo, c->fieldscount); - for (i=0; i < c->methodscount; i++) method_free ( &(c->methods[i]) ); + for (i = 0; i < c->methodscount; i++) + method_free(&(c->methods[i])); MFREE (c->methods, methodinfo, c->methodscount); - if ( (v = c->vftbl) ) { - for (i=0; iinterfacetablelength; i++) { - MFREE (v->interfacevftbl[i], methodptr, v->interfacevftbllength[i]); + if ((v = c->vftbl) != NULL) { + for (i = 0; i < v->interfacetablelength; i++) { + MFREE (v->interfacetable[-i], methodptr, v->interfacevftbllength[i]); } - MFREE (v->interfacevftbllength, u4, v->interfacetablelength); - MFREE (v->interfacevftbl, methodptr*, v->interfacetablelength); - - mem_free (v, sizeof(vftbl) + sizeof(methodptr) * (v->vftbllength - 1)); + MFREE (v->interfacevftbllength, s4, v->interfacetablelength); + + i = sizeof(vftbl) + sizeof(methodptr) * (v->vftbllength - 1) + + sizeof(methodptr*) * (v->interfacetablelength - + (v->interfacetablelength > 0)); + v = (vftbl*) (((methodptr*) v) - (v->interfacetablelength - 1) * + (v->interfacetablelength > 1)); + mem_free (v, i); } FREE (c, classinfo); } -/************************* Funktion: class_findfield ************************* +/************************* Funktion: class_findfield *************************** sucht in einer 'classinfo'-Struktur nach einem Feld mit gew"unschtem Namen und Typ. -*****************************************************************************/ +*******************************************************************************/ fieldinfo *class_findfield (classinfo *c, unicode *name, unicode *desc) { - u4 i; - for (i=0; i < c->fieldscount; i++) { - if ( (c->fields[i].name == name) && (c->fields[i].descriptor == desc) ) + s4 i; + for (i = 0; i < c->fieldscount; i++) { + if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) return &(c->fields[i]); } panic ("Can not find field given in CONSTANT_Fieldref"); @@ -1523,34 +1540,31 @@ fieldinfo *class_findfield (classinfo *c, unicode *name, unicode *desc) } -/************************* Funktion: class_findmethod ************************* +/************************* Funktion: class_findmethod ************************** sucht in einer 'classinfo'-Struktur nach einer Methode mit gew"unschtem Namen und Typ. Wenn als Typ NULL angegeben wird, dann ist der Typ egal. -*****************************************************************************/ +*******************************************************************************/ methodinfo *class_findmethod (classinfo *c, unicode *name, unicode *desc) { - u4 i; - for (i=0; i < c->methodscount; i++) { - if ( (c->methods[i].name == name) - && ( (desc == NULL) - || (c->methods[i].descriptor == desc) - ) - ) + s4 i; + for (i = 0; i < c->methodscount; i++) { + if ((c->methods[i].name == name) && ((desc == NULL) || + (c->methods[i].descriptor == desc))) return &(c->methods[i]); } return NULL; } -/************************* Funktion: class_resolvemethod ************************* +/************************* Funktion: class_resolvemethod *********************** sucht eine Klasse und alle Superklassen ab, um eine Methode zu finden. -*****************************************************************************/ +*******************************************************************************/ methodinfo *class_resolvemethod (classinfo *c, unicode *name, unicode *desc) @@ -1565,11 +1579,11 @@ methodinfo *class_resolvemethod (classinfo *c, unicode *name, unicode *desc) -/************************* Funktion: class_issubclass ************************ +/************************* Funktion: class_issubclass ************************** "uberpr"uft, ob eine Klasse von einer anderen Klasse abgeleitet ist. -*****************************************************************************/ +*******************************************************************************/ bool class_issubclass (classinfo *sub, classinfo *super) { @@ -1582,14 +1596,14 @@ bool class_issubclass (classinfo *sub, classinfo *super) -/****************** Initialisierungsfunktion f"ur eine Klasse **************** +/****************** Initialisierungsfunktion f"ur eine Klasse ****************** In Java kann jede Klasse ein statische Initialisierungsfunktion haben. Diese Funktion mu"s aufgerufen werden, BEVOR irgendwelche Methoden der Klasse aufgerufen werden, oder auf statische Variablen zugegriffen wird. -******************************************************************************/ +*******************************************************************************/ #ifdef USE_THREADS extern int blockInts; @@ -1660,7 +1674,7 @@ void class_init (classinfo *c) -/********* Funktion: class_showconstantpool (nur f"ur Debug-Zwecke) ********/ +/********* Funktion: class_showconstantpool (nur f"ur Debug-Zwecke) *********/ void class_showconstantpool (classinfo *c) { @@ -1752,11 +1766,11 @@ void class_showconstantpool (classinfo *c) -/********** Funktion: class_showmethods (nur f"ur Debug-Zwecke) ************/ +/********** Funktion: class_showmethods (nur f"ur Debug-Zwecke) *************/ void class_showmethods (classinfo *c) { - u4 i; + s4 i; printf ("--------- Fields and Methods ----------------\n"); printf ("Flags: "); printflags (c->flags); printf ("\n"); @@ -1798,18 +1812,18 @@ void class_showmethods (classinfo *c) -/*****************************************************************************/ -/******************* Funktionen fuer den Class-loader generell ***************/ -/*****************************************************************************/ +/******************************************************************************/ +/******************* Funktionen fuer den Class-loader generell ****************/ +/******************************************************************************/ -/********************* Funktion: loader_load ********************************** +/********************* Funktion: loader_load *********************************** l"adt und linkt die ge"unschte Klasse und alle davon referenzierten Klassen und Interfaces Return: Einen Zeiger auf diese Klasse -******************************************************************************/ +*******************************************************************************/ classinfo *loader_load (unicode *topname) { @@ -1842,11 +1856,11 @@ classinfo *loader_load (unicode *topname) } -/******************* interne Funktion: loader_createarrayclass **************** +/******************* interne Funktion: loader_createarrayclass ***************** Erzeugt (und linkt) eine Klasse f"ur die Arrays. -******************************************************************************/ +*******************************************************************************/ static classinfo *loader_createarrayclass () { @@ -1863,12 +1877,12 @@ static classinfo *loader_createarrayclass () -/********************** Funktion: loader_init ********************************* +/********************** Funktion: loader_init ********************************** Initialisiert alle Listen und l"adt alle Klassen, die vom System und vom Compiler direkt ben"otigt werden. -******************************************************************************/ +*******************************************************************************/ void loader_init () { @@ -1943,7 +1957,7 @@ void loader_init () initialisiert alle geladenen aber noch nicht initialisierten Klassen -******************************************************************************/ +*******************************************************************************/ void loader_initclasses () { @@ -1968,19 +1982,19 @@ static void loader_compute_class_values (classinfo *c) { classinfo *subs; - c->vftbl->lowclassval = classvalue++; + c->vftbl->baseval = ++classvalue; subs = c->sub; while (subs != NULL) { loader_compute_class_values(subs); subs = subs->nextsub; } - c->vftbl->highclassval = classvalue++; + c->vftbl->diffval = classvalue - c->vftbl->baseval; /* { int i; for (i = 0; i < c->index; i++) printf(" "); - printf("%3d %3d ", (int) c->vftbl->lowclassval, (int) c->vftbl->highclassval); + printf("%3d %3d ", (int) c->vftbl->baseval, c->vftbl->diffval); unicode_display(c->name); printf("\n"); } @@ -2010,11 +2024,11 @@ void loader_compute_subclasses () -/******************** Funktion: loader_close ********************************** +/******************** Funktion: loader_close *********************************** gibt alle Resourcen wieder frei -******************************************************************************/ +*******************************************************************************/ void loader_close () { @@ -2034,3 +2048,16 @@ void loader_close () } } + +/* + * These are local overrides for various environment variables in Emacs. + * Please do not remove this and leave it at the end of the file, where + * Emacs will automagically detect them. + * --------------------------------------------------------------------- + * Local variables: + * mode: c + * indent-tabs-mode: t + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ -- 2.25.1