X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=builtin.c;h=1278ac04517bb055efff434b433c2d97599b1396;hb=582856bd30b921eb5e16a1fe5f9f90a4320cfedb;hp=eb35877842f71955764a07593bce3045ab7de893;hpb=bc55009838ad3931e78e6b3d54f9f4b75a6b4e66;p=cacao.git diff --git a/builtin.c b/builtin.c index eb3587784..1278ac045 100644 --- a/builtin.c +++ b/builtin.c @@ -34,7 +34,7 @@ calls instead of machine instructions, using the C calling convention. - $Id: builtin.c 779 2003-12-14 18:11:35Z stefan $ + $Id: builtin.c 951 2004-03-11 17:30:03Z jowenn $ */ @@ -49,6 +49,7 @@ #include "loader.h" #include "tables.h" #include "asmpart.h" +#include "mm/boehm.h" #include "threads/thread.h" #include "threads/locks.h" #include "toolbox/loging.h" @@ -59,103 +60,9 @@ #undef DEBUG /*define DEBUG 1*/ -/* XXX delete? */ -#if 0 -builtin_descriptor builtin_desc[] = { - {(functionptr) builtin_instanceof, "instanceof"}, - {(functionptr) builtin_checkcast, "checkcast"}, - {(functionptr) asm_builtin_checkcast, "checkcast"}, - {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"}, -#if defined(__I386__) - {(functionptr) asm_builtin_arrayinstanceof,"arrayinstanceof"}, -#endif - {(functionptr) builtin_checkarraycast, "checkarraycast"}, - {(functionptr) asm_builtin_checkarraycast, "checkarraycast"}, - {(functionptr) asm_builtin_aastore, "aastore"}, - {(functionptr) builtin_new, "new"}, - {(functionptr) builtin_newarray, "newarray"}, - {(functionptr) builtin_anewarray, "anewarray"}, -#if defined(__I386__) - /* - * have 2 parameters (needs stack manipulation) - */ - {(functionptr) asm_builtin_newarray, "newarray"}, -#endif - {(functionptr) builtin_newarray_boolean, "newarray_boolean"}, - {(functionptr) builtin_newarray_char, "newarray_char"}, - {(functionptr) builtin_newarray_float, "newarray_float"}, - {(functionptr) builtin_newarray_double, "newarray_double"}, - {(functionptr) builtin_newarray_byte, "newarray_byte"}, - {(functionptr) builtin_newarray_short, "newarray_short"}, - {(functionptr) builtin_newarray_int, "newarray_int"}, - {(functionptr) builtin_newarray_long, "newarray_long"}, - {(functionptr) builtin_displaymethodstart, "displaymethodstart"}, - {(functionptr) builtin_displaymethodstop, "displaymethodstop"}, - {(functionptr) builtin_monitorenter, "monitorenter"}, - {(functionptr) asm_builtin_monitorenter, "monitorenter"}, - {(functionptr) builtin_monitorexit, "monitorexit"}, - {(functionptr) asm_builtin_monitorexit, "monitorexit"}, -#if !SUPPORT_DIVISION - {(functionptr) builtin_idiv, "idiv"}, - {(functionptr) asm_builtin_idiv, "idiv"}, - {(functionptr) builtin_irem, "irem"}, - {(functionptr) asm_builtin_irem, "irem"}, -#endif - {(functionptr) builtin_ladd, "ladd"}, - {(functionptr) builtin_lsub, "lsub"}, - {(functionptr) builtin_lmul, "lmul"}, -#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) - {(functionptr) builtin_ldiv, "ldiv"}, - {(functionptr) asm_builtin_ldiv, "ldiv"}, - {(functionptr) builtin_lrem, "lrem"}, - {(functionptr) asm_builtin_lrem, "lrem"}, -#endif - {(functionptr) builtin_lshl, "lshl"}, - {(functionptr) builtin_lshr, "lshr"}, - {(functionptr) builtin_lushr, "lushr"}, - {(functionptr) builtin_land, "land"}, - {(functionptr) builtin_lor, "lor"}, - {(functionptr) builtin_lxor, "lxor"}, - {(functionptr) builtin_lneg, "lneg"}, - {(functionptr) builtin_lcmp, "lcmp"}, - {(functionptr) builtin_fadd, "fadd"}, - {(functionptr) builtin_fsub, "fsub"}, - {(functionptr) builtin_fmul, "fmul"}, - {(functionptr) builtin_fdiv, "fdiv"}, - {(functionptr) builtin_frem, "frem"}, - {(functionptr) builtin_fneg, "fneg"}, - {(functionptr) builtin_fcmpl, "fcmpl"}, - {(functionptr) builtin_fcmpg, "fcmpg"}, - {(functionptr) builtin_dadd, "dadd"}, - {(functionptr) builtin_dsub, "dsub"}, - {(functionptr) builtin_dmul, "dmul"}, - {(functionptr) builtin_ddiv, "ddiv"}, - {(functionptr) builtin_drem, "drem"}, - {(functionptr) builtin_dneg, "dneg"}, - {(functionptr) builtin_dcmpl, "dcmpl"}, - {(functionptr) builtin_dcmpg, "dcmpg"}, - {(functionptr) builtin_i2l, "i2l"}, - {(functionptr) builtin_i2f, "i2f"}, - {(functionptr) builtin_i2d, "i2d"}, - {(functionptr) builtin_l2i, "l2i"}, - {(functionptr) builtin_l2f, "l2f"}, - {(functionptr) builtin_l2d, "l2d"}, - {(functionptr) builtin_f2i, "f2i"}, - {(functionptr) builtin_f2l, "f2l"}, - {(functionptr) builtin_f2d, "f2d"}, - {(functionptr) builtin_d2i, "d2i"}, - {(functionptr) builtin_d2l, "d2l"}, -#if defined(__I386__) - {(functionptr) asm_builtin_f2i, "f2i"}, - {(functionptr) asm_builtin_f2l, "f2l"}, - {(functionptr) asm_builtin_d2i, "d2i"}, - {(functionptr) asm_builtin_d2l, "d2l"}, -#endif - {(functionptr) builtin_d2f, "d2f"}, - {(functionptr) NULL, "unknown"} -}; -#endif +THREADSPECIFIC methodinfo* _threadrootmethod = NULL; +THREADSPECIFIC void *_thread_nativestackframeinfo=NULL; /***************************************************************************** TYPE CHECKS @@ -171,9 +78,10 @@ builtin_descriptor builtin_desc[] = { 0 ... otherwise *****************************************************************************/ - -s4 builtin_isanysubclass (classinfo *sub, classinfo *super) +s4 builtin_isanysubclass(classinfo *sub, classinfo *super) { + s4 res; + /*classinfo *tmp;*/ if (super->flags & ACC_INTERFACE) return (sub->vftbl->interfacetablelength > super->index) && @@ -211,7 +119,7 @@ s4 builtin_isanysubclass (classinfo *sub, classinfo *super) cast_lock(); #endif - s4 res = (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <= + res = (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <= (unsigned) (super->vftbl->diffval); #if defined(USE_THREADS) && defined(NATIVE_THREADS) @@ -221,7 +129,6 @@ s4 builtin_isanysubclass (classinfo *sub, classinfo *super) return res; } -/* XXX inline this? */ s4 builtin_isanysubclass_vftbl(vftbl *sub,vftbl *super) { int base; @@ -308,7 +215,6 @@ s4 builtin_checkcast(java_objectheader *obj, classinfo *class) ******************************************************************************/ -/* XXX inline this? */ static s4 builtin_descriptorscompatible(arraydescriptor *desc,arraydescriptor *target) { if (desc==target) return 1; @@ -316,8 +222,11 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,arraydescriptor *t if (desc->arraytype != ARRAYTYPE_OBJECT) return 1; /* {both arrays are arrays of references} */ - if (desc->dimension == target->dimension) + if (desc->dimension == target->dimension) { + /* an array which contains elements of interface types is allowed to be casted to Object (JOWENN)*/ + if ( (desc->elementvftbl->baseval<0) && (target->elementvftbl->baseval==1) ) return 1; return builtin_isanysubclass_vftbl(desc->elementvftbl,target->elementvftbl); + } if (desc->dimension < target->dimension) return 0; /* {desc has higher dimension than target} */ @@ -386,10 +295,23 @@ java_objectheader *builtin_throw_exception(java_objectheader *local_exceptionptr } log_text(logtext); } - exceptionptr = local_exceptionptr; + *exceptionptr = local_exceptionptr; return local_exceptionptr; } +void builtin_reset_exceptionptr() +{ +#if defined(USE_THREADS) && defined(NATIVE_THREADS) +#ifdef HAVE___THREAD + _exceptionptr = NULL; +#else + ((nativethread*) pthread_getspecific(tkey_exceptionptr))->_exceptionptr = 0; +#endif +#else + panic("builtin_reset_exceptionptr should not be used in this configuration"); +#endif +} + /******************* function: builtin_canstore ******************************* @@ -510,7 +432,6 @@ s4 builtin_canstore_onedim (java_objectarray *a, java_objectheader *o) /* This is an optimized version where a is guaranteed to be a * one-dimensional array of a class type */ -/* XXX this could be inlined by the code generator */ s4 builtin_canstore_onedim_class(java_objectarray *a, java_objectheader *o) { vftbl *elementvftbl; @@ -565,8 +486,21 @@ s4 builtin_canstore_onedim_class(java_objectarray *a, java_objectheader *o) java_objectheader *builtin_new(classinfo *c) { java_objectheader *o; - - class_init(c); +/*DEBUGING - NOT THREAD SAFE*/ +/* static long depth=0; + depth++; + printf("Entering builtin_new:depth(%ld)",depth);*/ + + if (!c->initialized) { + if (initverbose) { + char logtext[MAXLOGTEXT]; + sprintf(logtext, "Initialize class "); + utf_sprint(logtext + strlen(logtext), c->name); + sprintf(logtext + strlen(logtext), " (from builtin_new)"); + log_text(logtext); + } + class_init(c); + } #ifdef SIZE_FROM_CLASSINFO c->alignedsize = align_size(c->instancesize); @@ -574,12 +508,20 @@ java_objectheader *builtin_new(classinfo *c) #else o = heap_allocate(c->instancesize, true, c->finalizer); #endif - if (!o) return NULL; + if (!o) { + /*DEBUGING - NOT THREAD SAFE*/ + /*printf("Leaving builtin_new: depth(%ld): NULL",depth); + depth--;*/ + return NULL; + } memset(o, 0, c->instancesize); o->vftbl = c->vftbl; + /*DEBUGING - NOT THREAD SAFE*/ + /* printf("Leaving builtin_new: depth(%ld): object",depth); + depth--;*/ return o; } @@ -596,42 +538,43 @@ java_objectheader *builtin_new(classinfo *c) java_arrayheader *builtin_newarray(s4 size, vftbl *arrayvftbl) { - java_arrayheader *a; - arraydescriptor *desc = arrayvftbl->arraydesc; - s4 dataoffset = desc->dataoffset; - s4 componentsize = desc->componentsize; - s4 actualsize; + java_arrayheader *a; + arraydescriptor *desc = arrayvftbl->arraydesc; + s4 dataoffset = desc->dataoffset; + s4 componentsize = desc->componentsize; + s4 actualsize; if (size<0) { - exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/NegativeArraySizeException"))); + *exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/NegativeArraySizeException"))); return NULL; } #ifdef SIZE_FROM_CLASSINFO - actualsize = align_size(dataoffset + size * componentsize); + actualsize = align_size(dataoffset + size * componentsize); #else - actualsize = dataoffset + size * componentsize; + actualsize = dataoffset + size * componentsize; #endif - if (((u4)actualsize)<((u4)size)) { /* overflow */ - exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/OutOfMemoryError"))); + if (((u4)actualsize)<((u4)size)) { /* overflow */ + *exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/OutOfMemoryError"))); return NULL; } - a = (java_arrayheader *) heap_allocate(actualsize, - (desc->arraytype == ARRAYTYPE_OBJECT), - NULL); - if (!a) return NULL; - memset(a,0,actualsize); + a = heap_allocate(actualsize, + (desc->arraytype == ARRAYTYPE_OBJECT), + NULL); + + if (!a) return NULL; + memset(a, 0, actualsize); /*printf("builtin_newarray: Created an array of size : %d\n",size);*/ - a->objheader.vftbl = arrayvftbl; - a->size = size; + a->objheader.vftbl = arrayvftbl; + a->size = size; #ifdef SIZE_FROM_CLASSINFO - a->alignedsize = actualsize; + a->alignedsize = actualsize; #endif - return a; + return a; } @@ -649,6 +592,12 @@ java_arrayheader *builtin_newarray(s4 size, vftbl *arrayvftbl) java_objectarray *builtin_anewarray(s4 size, classinfo *component) { +/* + printf("builtin_anewarray: classvftbl: %d\n",component->classvftbl); + printf("builtin_anewarray: baseval: %d\n",component->vftbl->baseval); + utf_display(component->vftbl->class->name); + printf("\nbuiltin_anewarray: linked: %d\n",component->linked); + utf_display(component->super->name);*/ return (java_objectarray*) builtin_newarray(size, class_array_of(component)->vftbl); } @@ -798,8 +747,10 @@ java_arrayheader *builtin_nmultianewarray (int n, vftbl *arrayvftbl, long *dims) /* get the vftbl of the components to create */ componentvftbl = arrayvftbl->arraydesc->componentvftbl; - if (!componentvftbl) /* XXX the verifier could check this */ - panic ("multianewarray with too many dimensions"); + + /* The verifier guarantees this. */ + /* if (!componentvftbl) */ + /* panic ("multianewarray with too many dimensions"); */ /* create the component arrays */ for (i = 0; i < size; i++) { @@ -824,18 +775,22 @@ java_arrayheader *builtin_nmultianewarray (int n, vftbl *arrayvftbl, long *dims) u4 methodindent = 0; -java_objectheader *builtin_trace_exception(java_objectheader *exceptionptr, +java_objectheader *builtin_trace_exception(java_objectheader *_exceptionptr, methodinfo *method, int *pos, int noindent) { - if (!noindent) - methodindent--; + if (!noindent) { + if (methodindent) + methodindent--; + else + log_text("WARNING: unmatched methodindent--"); + } if (verbose || runverbose) { printf("Exception "); - if (exceptionptr) { - utf_display (exceptionptr->vftbl->class->name); - } - else { + if (_exceptionptr) { + utf_display(_exceptionptr->vftbl->class->name); + + } else { printf("Error: "); if (!proto_java_lang_ClassCastException) printf("%s","proto_java_lang_ClassCastException==0"); if (!proto_java_lang_NullPointerException) printf("%s","proto_java_lang_NullPointerException==0"); @@ -850,21 +805,23 @@ java_objectheader *builtin_trace_exception(java_objectheader *exceptionptr, } printf(" thrown in "); + if (method) { - utf_display (method->class->name); + utf_display(method->class->name); printf("."); - utf_display (method->name); + utf_display(method->name); if (method->flags & ACC_SYNCHRONIZED) printf("(SYNC)"); else printf("(NOSYNC)"); printf("(%p) at position %p\n", method->entrypoint, pos); - } - else + + } else printf("call_java_method\n"); fflush (stdout); } - return exceptionptr; + + return _exceptionptr; } @@ -884,6 +841,20 @@ void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5, sprintf(logtext + strlen(logtext), "."); utf_sprint(logtext + strlen(logtext), method->name); utf_sprint(logtext + strlen(logtext), method->descriptor); + + if ( method->flags & ACC_PUBLIC ) sprintf (logtext + strlen(logtext)," PUBLIC"); + if ( method->flags & ACC_PRIVATE ) sprintf (logtext + strlen(logtext)," PRIVATE"); + if ( method->flags & ACC_PROTECTED ) sprintf (logtext + strlen(logtext)," PROTECTED"); + if ( method->flags & ACC_STATIC ) sprintf (logtext + strlen(logtext)," STATIC"); + if ( method->flags & ACC_FINAL ) sprintf (logtext + strlen(logtext)," FINAL"); + if ( method->flags & ACC_SYNCHRONIZED ) sprintf (logtext + strlen(logtext)," SYNCHRONIZED"); + if ( method->flags & ACC_VOLATILE ) sprintf (logtext + strlen(logtext)," VOLATILE"); + if ( method->flags & ACC_TRANSIENT ) sprintf (logtext + strlen(logtext)," TRANSIENT"); + if ( method->flags & ACC_NATIVE ) sprintf (logtext + strlen(logtext)," NATIVE"); + if ( method->flags & ACC_INTERFACE ) sprintf (logtext + strlen(logtext)," INTERFACE"); + if ( method->flags & ACC_ABSTRACT ) sprintf (logtext + strlen(logtext)," ABSTRACT"); + + sprintf(logtext + strlen(logtext), "("); switch (method->paramcount) { @@ -1007,6 +978,19 @@ void builtin_displaymethodstart(methodinfo *method) sprintf(logtext + strlen(logtext), "."); utf_sprint(logtext + strlen(logtext), method->name); utf_sprint(logtext + strlen(logtext), method->descriptor); + + if ( method->flags & ACC_PUBLIC ) sprintf (logtext + strlen(logtext)," PUBLIC"); + if ( method->flags & ACC_PRIVATE ) sprintf (logtext + strlen(logtext)," PRIVATE"); + if ( method->flags & ACC_PROTECTED ) sprintf (logtext + strlen(logtext)," PROTECTED"); + if ( method->flags & ACC_STATIC ) sprintf (logtext + strlen(logtext)," STATIC"); + if ( method->flags & ACC_FINAL ) sprintf (logtext + strlen(logtext)," FINAL"); + if ( method->flags & ACC_SYNCHRONIZED ) sprintf (logtext + strlen(logtext)," SYNCHRONIZED"); + if ( method->flags & ACC_VOLATILE ) sprintf (logtext + strlen(logtext)," VOLATILE"); + if ( method->flags & ACC_TRANSIENT ) sprintf (logtext + strlen(logtext)," TRANSIENT"); + if ( method->flags & ACC_NATIVE ) sprintf (logtext + strlen(logtext)," NATIVE"); + if ( method->flags & ACC_INTERFACE ) sprintf (logtext + strlen(logtext)," INTERFACE"); + if ( method->flags & ACC_ABSTRACT ) sprintf (logtext + strlen(logtext)," ABSTRACT"); + log_text(logtext); methodindent++; } @@ -1018,7 +1002,10 @@ void builtin_displaymethodstop(methodinfo *method, s8 l, double d, float f) char logtext[MAXLOGTEXT]; for (i = 0; i < methodindent; i++) logtext[i] = '\t'; - methodindent--; + if (methodindent) + methodindent--; + else + log_text("WARNING: unmatched methodindent--"); sprintf(logtext + methodindent, "finished: "); utf_sprint(logtext + strlen(logtext), method->class->name); sprintf(logtext + strlen(logtext), "."); @@ -1078,7 +1065,7 @@ void builtin_displaymethodexception(methodinfo *method) */ void internal_lock_mutex_for_object(java_objectheader *object) { -#ifdef USE_THREADS +#if defined(USE_THREADS) && !defined(NATIVE_THREADS) mutexHashEntry *entry; int hashValue; @@ -1128,7 +1115,7 @@ void internal_lock_mutex_for_object(java_objectheader *object) */ void internal_unlock_mutex_for_object (java_objectheader *object) { -#ifdef USE_THREADS +#if defined(USE_THREADS) && !defined(NATIVE_THREADS) int hashValue; mutexHashEntry *entry; @@ -1160,7 +1147,7 @@ void internal_unlock_mutex_for_object (java_objectheader *object) void builtin_monitorenter(java_objectheader *o) { -#ifdef USE_THREADS +#if defined(USE_THREADS) && !defined(NATIVE_THREADS) int hashValue; assert(blockInts == 0); @@ -1183,7 +1170,7 @@ void builtin_monitorenter(java_objectheader *o) void builtin_monitorexit (java_objectheader *o) { -#ifdef USE_THREADS +#if defined(USE_THREADS) && !defined(NATIVE_THREADS) int hashValue; assert(blockInts == 0); @@ -1800,10 +1787,37 @@ inline float longBitsToDouble(s8 l) java_arrayheader *builtin_clone_array(void *env, java_arrayheader *o) { - return Java_java_lang_VMObject_clone(0, 0, o); + return (java_arrayheader *) Java_java_lang_VMObject_clone(0, 0, (java_lang_Cloneable *) o); +} + +s4 builtin_dummy() +{ + panic("Internal error: builtin_dummy called (native function is missing)"); + return 0; /* for the compiler */ +} + + +inline methodinfo *builtin_asm_get_threadrootmethod() { + return *threadrootmethod; } +inline void* +builtin_asm_get_stackframeinfo(){ +/*log_text("builtin_asm_get_stackframeinfo()");*/ +#if defined(USE_THREADS) && defined(NATIVE_THREADS) +#ifdef HAVE___THREAD + return &_thread_nativestackframeinfo; /*support for __thread attribute*/ +#else + return &((nativethread*) pthread_getspecific(tkey_stackframeinfo))->_stackframeinfo /*copied from exception handling, is that really */ + /*old pthread*/ +#endif +#else +#warning FIXME FOR OLD THREAD IMPL (jowenn) + return &_thread_nativestackframeinfo; /* no threading, at least no native*/ +#endif +} + /* * 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