X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fbuiltin.c;h=aa0165bd6ac284d22195eb506b130206d625b04b;hb=f05f0b616546c4560d0eae431bb4b5ecbb1f72e3;hp=f3e516257f2749b9a2a3ffb4378274b8f6d2ab9a;hpb=c820f5bbac4a3f5f54e2f9bda87b140366f32a86;p=cacao.git diff --git a/src/vm/builtin.c b/src/vm/builtin.c index f3e516257..aa0165bd6 100644 --- a/src/vm/builtin.c +++ b/src/vm/builtin.c @@ -34,7 +34,7 @@ calls instead of machine instructions, using the C calling convention. - $Id: builtin.c 782 2003-12-15 15:47:09Z twisti $ + $Id: builtin.c 967 2004-03-18 14:29:03Z jowenn $ */ @@ -60,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 @@ -223,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; @@ -310,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; @@ -318,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} */ @@ -388,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 ******************************* @@ -512,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; @@ -567,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); @@ -576,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; } @@ -605,7 +545,7 @@ java_arrayheader *builtin_newarray(s4 size, vftbl *arrayvftbl) 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 @@ -615,7 +555,7 @@ java_arrayheader *builtin_newarray(s4 size, vftbl *arrayvftbl) #endif if (((u4)actualsize)<((u4)size)) { /* overflow */ - exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/OutOfMemoryError"))); + *exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/OutOfMemoryError"))); return NULL; } a = heap_allocate(actualsize, @@ -652,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); } @@ -801,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,21 +772,27 @@ 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 line, int noindent) { - if (!noindent) - methodindent--; - if (verbose || runverbose) { - printf("Exception "); - if (exceptionptr) { - utf_display (exceptionptr->vftbl->class->name); - } - else { + if (!noindent) { + if (methodindent) + methodindent--; + else + log_text("WARNING: unmatched methodindent--"); + } + if (verbose || runverbose || verboseexception) { + if (_exceptionptr) { + printf("Exception "); + utf_display(_exceptionptr->vftbl->class->name); + + } else { + printf("Some Throwable"); +/* 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,24 +804,36 @@ java_objectheader *builtin_trace_exception(java_objectheader *exceptionptr, if (!proto_java_lang_ArrayStoreException) printf("%s","proto_java_lang_ArrayStoreException==0"); if (!proto_java_lang_ThreadDeath) printf("%s","proto_java_lang_ThreadDeath==0"); if (!proto_java_lang_ThreadDeath) printf("%s","proto_java_lang_ThreadDeath==0"); - + */ } printf(" thrown in "); + if (method) { - utf_display (method->class->name); + utf_display_classname(method->class->name); printf("."); - utf_display (method->name); + utf_display(method->name); if (method->flags & ACC_SYNCHRONIZED) - printf("(SYNC)"); + printf("(SYNC"); else - printf("(NOSYNC)"); - printf("(%p) at position %p\n", method->entrypoint, pos); - } - else + printf("(NOSYNC"); + if (method->flags & ACC_NATIVE) { + printf(",NATIVE"); + printf(")(%p) at position %p\n", method->entrypoint, pos); + } else { + printf(")(%p) at position %p (",method->entrypoint,pos); + if (method->class->sourcefile==NULL) + printf(""); + else + utf_display(method->class->sourcefile); + printf(":%d)\n",line); + } + + } else printf("call_java_method\n"); fflush (stdout); } - return exceptionptr; + + return _exceptionptr; } @@ -882,18 +848,33 @@ void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5, char logtext[MAXLOGTEXT]; for (i = 0; i < methodindent; i++) logtext[i] = '\t'; + sprintf(logtext + methodindent, "called: "); utf_sprint(logtext + strlen(logtext), method->class->name); 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) { case 0: break; -#if defined(__I386__) +#if defined(__I386__) || defined(__POWERPC__) case 1: sprintf(logtext+strlen(logtext), "%llx", a0); break; @@ -993,7 +974,8 @@ void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5, #endif #endif } - sprintf (logtext+strlen(logtext), ")"); + + sprintf(logtext + strlen(logtext), ")"); log_text(logtext); methodindent++; @@ -1010,6 +992,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++; } @@ -1021,7 +1016,11 @@ 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), "."); @@ -1032,23 +1031,27 @@ void builtin_displaymethodstop(methodinfo *method, s8 l, double d, float f) case TYPE_INT: sprintf(logtext + strlen(logtext), "->%d", (s4) l); break; + case TYPE_LONG: -#if defined(__I386__) +#if defined(__I386__) || defined(__POWERPC__) sprintf(logtext + strlen(logtext), "->%lld", (s8) l); #else sprintf(logtext + strlen(logtext), "->%ld", (s8) l); #endif break; + case TYPE_ADDRESS: -#if defined(__I386__) +#if defined(__I386__) || defined(__POWERPC__) sprintf(logtext + strlen(logtext), "->%p", (u1*) ((s4) l)); #else sprintf(logtext + strlen(logtext), "->%p", (u1*) l); #endif break; + case TYPE_FLOAT: sprintf(logtext + strlen(logtext), "->%g", f); break; + case TYPE_DOUBLE: sprintf(logtext + strlen(logtext), "->%g", d); break; @@ -1081,7 +1084,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; @@ -1131,7 +1134,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; @@ -1163,9 +1166,11 @@ 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; + /*log_text("Monitor enter");*/ + assert(blockInts == 0); ++blockInts; @@ -1186,9 +1191,12 @@ void builtin_monitorenter(java_objectheader *o) void builtin_monitorexit (java_objectheader *o) { -#ifdef USE_THREADS + +#if defined(USE_THREADS) && !defined(NATIVE_THREADS) int hashValue; + /* log_text("Monitor leave"); */ + assert(blockInts == 0); ++blockInts; @@ -1806,6 +1814,45 @@ java_arrayheader *builtin_clone_array(void *env, java_arrayheader *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 +} + +stacktraceelement *builtin_stacktrace_copy(stacktraceelement **el,stacktraceelement *begin, stacktraceelement *end) { +/* stacktraceelement *el;*/ + size_t s; + s=(end-begin); + /*printf ("begin: %p, end: %p, diff: %ld, size :%ld\n",begin,end,s,s*sizeof(stacktraceelement));*/ + *el=GCNEW(stacktraceelement,s+1); + memcpy(*el,begin,(end-begin)*sizeof(stacktraceelement)); + (*el)[s].method=0; + (*el)[s].linenumber=0; + return *el; +} /* * These are local overrides for various environment variables in Emacs.