X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvmcore%2Flinker.c;h=49cf74a678c4a805d048e62745ffbb678050960e;hb=9d4cb0889f6539fc4f2a82784dc4664b1a0f332d;hp=0c9f34af1121b6a16ff003ce24a5cc6e8fdb221f;hpb=312fe519b515aa7182f9dfdd510d5b461feb7bdf;p=cacao.git diff --git a/src/vmcore/linker.c b/src/vmcore/linker.c index 0c9f34af1..49cf74a67 100644 --- a/src/vmcore/linker.c +++ b/src/vmcore/linker.c @@ -1,9 +1,7 @@ /* src/vmcore/linker.c - class linker functions - Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel, - C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring, - E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, - J. Wenninger, Institut f. Computersprachen - TU Wien + Copyright (C) 1996-2005, 2006, 2007, 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -42,19 +40,39 @@ #include "vm/access.h" #include "vm/array.h" -#include "vm/exceptions.h" -#include "vm/primitive.h" -#include "vm/stringlocal.h" -#include "vm/vm.h" +#include "vm/exceptions.hpp" +#include "vm/primitive.hpp" +#include "vm/string.hpp" +#include "vm/vm.hpp" #include "vm/jit_interface.h" #include "vmcore/class.h" #include "vmcore/classcache.h" +#include "vmcore/globals.hpp" #include "vmcore/loader.h" #include "vmcore/options.h" #include "vmcore/rt-timing.h" + +/* debugging macros ***********************************************************/ + +#if !defined(NDEBUG) +# define TRACELINKCLASS(c) \ + do { \ + if (opt_TraceLinkClass) { \ + log_start(); \ + log_print("[Linking "); \ + class_print((c)); \ + log_print("]"); \ + log_finish(); \ + } \ + } while (0) +#else +# define TRACELINKCLASS(c) +#endif + + /* #include "vm/resolve.h" */ /* copied prototype to avoid bootstrapping problem: */ classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess); @@ -64,7 +82,7 @@ classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool c #endif #if !defined(NDEBUG) && defined(ENABLE_INLINING) -#define INLINELOG(code) do { if (opt_inline_debug_log) { code } } while (0) +#define INLINELOG(code) do { if (opt_TraceInlining) { code } } while (0) #else #define INLINELOG(code) #endif @@ -113,10 +131,17 @@ struct dummy_alignment_double_t { void linker_preinit(void) { + TRACESUBSYSTEMINITIALIZATION("linker_preinit"); + /* Check for if alignment for long and double matches what we assume for the current architecture. */ -#if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__)) +#if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__)) || defined(__M68K__) + /* Define a define here which is later checked when we use this + offset. */ + +# define LINKER_ALIGNMENT_LONG_DOUBLE 4 + if (OFFSET(dummy_alignment_long_t, l) != 4) vm_abort("linker_preinit: long alignment is different from what assumed: %d != %d", OFFSET(dummy_alignment_long_t, l), 4); @@ -125,6 +150,9 @@ void linker_preinit(void) vm_abort("linker_preinit: double alignment is different from what assumed: %d != %d", OFFSET(dummy_alignment_double_t, d), 4); #else + +# define LINKER_ALIGNMENT_LONG_DOUBLE 8 + if (OFFSET(dummy_alignment_long_t, l) != 8) vm_abort("linker_preinit: long alignment is different from what assumed: %d != %d", OFFSET(dummy_alignment_long_t, l), 8); @@ -169,6 +197,8 @@ void linker_preinit(void) void linker_init(void) { + TRACESUBSYSTEMINITIALIZATION("linker_init"); + /* Link java.lang.Class as first class of the system, because we need it's vftbl for all other classes so we can use a class as object. */ @@ -236,14 +266,30 @@ void linker_init(void) vm_abort("linker_init: linking failed"); #endif -#if defined(WITH_CLASSPATH_GNU) + if (!link_class(class_java_lang_Throwable)) + vm_abort("linker_init: linking failed"); + +#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) if (!link_class(class_java_lang_VMSystem)) vm_abort("linker_init: linking failed"); if (!link_class(class_java_lang_VMThread)) vm_abort("linker_init: linking failed"); + + if (!link_class(class_java_lang_VMThrowable)) + vm_abort("linker_init: linking failed"); #endif + /* Important system exceptions. */ + + if (!link_class(class_java_lang_Exception)) + vm_abort("linker_init: linking failed"); + + if (!link_class(class_java_lang_ClassNotFoundException)) + vm_abort("linker_init: linking failed"); + + if (!link_class(class_java_lang_RuntimeException)) + vm_abort("linker_init: linking failed"); /* some classes which may be used more often */ @@ -260,13 +306,30 @@ void linker_init(void) if (!link_class(class_java_lang_reflect_Method)) vm_abort("linker_init: linking failed"); +# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) + if (!link_class(class_java_lang_reflect_VMConstructor)) + vm_abort("linker_init: linking failed"); + + if (!link_class(class_java_lang_reflect_VMField)) + vm_abort("linker_init: linking failed"); + + if (!link_class(class_java_lang_reflect_VMMethod)) + vm_abort("linker_init: linking failed"); +# endif + if (!link_class(class_java_security_PrivilegedAction)) vm_abort("linker_init: linking failed"); if (!link_class(class_java_util_Vector)) vm_abort("linker_init: linking failed"); -# if defined(WITH_CLASSPATH_SUN) + if (!link_class(class_java_util_HashMap)) + vm_abort("linker_init: linking failed"); + +# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) + if (!link_class(class_sun_misc_Signal)) + vm_abort("linker_init: linking failed"); + if (!link_class(class_sun_reflect_MagicAccessorImpl)) vm_abort("linker_init: linking failed"); # endif @@ -430,8 +493,8 @@ static bool linker_overwrite_method(methodinfo *mg, classinfo *cg; classinfo *cs; - cg = mg->class; - cs = ms->class; + cg = mg->clazz; + cs = ms->clazz; /* overriding a final method is illegal */ @@ -464,6 +527,15 @@ static bool linker_overwrite_method(methodinfo *mg, if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) { do { + +#if defined(ENABLE_TLH) + if (mg->flags & ACC_METHOD_MONOMORPHY_USED) { + printf("%s/%s is evil! the siner is %s/%s\n", mg->clazz->name->text, mg->name->text, + ms->clazz->name->text, ms->name->text); + ms->flags |= ACC_METHOD_PARENT_MONOMORPHY_USED; + } +#endif + if (mg->flags & ACC_METHOD_IMPLEMENTED) { /* this adds another implementation */ @@ -518,10 +590,7 @@ static classinfo *link_class_intern(classinfo *c) RT_TIMING_GET_TIME(time_start); -#if !defined(NDEBUG) - if (linkverbose) - log_message_class("Linking class: ", c); -#endif + TRACELINKCLASS(c); /* the class must be loaded */ @@ -731,7 +800,7 @@ static classinfo *link_class_intern(classinfo *c) MCOPY(am, im, methodinfo, 1); am->vftblindex = (vftbllength++); - am->class = c; + am->clazz = c; am->flags |= ACC_MIRANDA; noabstractmethod2: @@ -772,7 +841,7 @@ static classinfo *link_class_intern(classinfo *c) (interfacetablelength - 1) * (interfacetablelength > 1)); c->vftbl = v; - v->class = c; + v->clazz = c; v->vftbllength = vftbllength; v->interfacetablelength = interfacetablelength; v->arraydesc = arraydesc; @@ -849,16 +918,25 @@ static classinfo *link_class_intern(classinfo *c) if (!(f->flags & ACC_STATIC)) { dsize = descriptor_typesize(f->parseddesc); -#if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__)) - /* On i386 and ARM we align double and s8 fields to - 4-bytes. This matches what GCC does for struct - members. We must do the same as gcc here because the - offsets in native header structs like java_lang_Double - must match the offsets of the Java fields - (eg. java.lang.Double.value). */ +#if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__)) || defined(__M68K__) + /* On some architectures and configurations we need to + align long (int64_t) and double fields to 4-bytes to + match what GCC does for struct members. We must do the + same as GCC here because the offsets in native header + structs like java_lang_Double must match the offsets of + the Java fields (eg. java.lang.Double.value). */ + +# if LINKER_ALIGNMENT_LONG_DOUBLE != 4 +# error alignment of long and double is not 4 +# endif c->instancesize = MEMORY_ALIGN(c->instancesize, 4); #else + +# if LINKER_ALIGNMENT_LONG_DOUBLE != 8 +# error alignment of long and double is not 8 +# endif + c->instancesize = MEMORY_ALIGN(c->instancesize, dsize); #endif @@ -930,11 +1008,6 @@ static classinfo *link_class_intern(classinfo *c) FREE(wi, method_worklist); } -#if !defined(NDEBUG) - if (linkverbose) - log_message_class("Linking done class: ", c); -#endif - RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE); RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL); RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT); @@ -1116,10 +1189,6 @@ static void linker_compute_subclasses(classinfo *c) { LOCK_MONITOR_ENTER(linker_classrenumber_lock); -#if 0 && defined(ENABLE_THREADS) && !defined(DISABLE_GC) - threads_stopworld(); -#endif - if (!(c->flags & ACC_INTERFACE)) { c->nextsub = NULL; c->sub = NULL; @@ -1137,10 +1206,6 @@ static void linker_compute_subclasses(classinfo *c) linker_compute_class_values(class_java_lang_Object); LOCK_MONITOR_EXIT(linker_classrenumber_lock); - -#if 0 && defined(ENABLE_THREADS) && !defined(DISABLE_GC) - threads_startworld(); -#endif }