Edwin Steiner
Christian Thalinger
- $Id: linker.c 5056 2006-06-28 21:01:21Z edwin $
+ $Id: linker.c 5868 2006-10-30 11:21:36Z edwin $
*/
#include "mm/memory.h"
#include "native/native.h"
-#include "vm/builtin.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/lock.h"
+#else
+# include "threads/none/lock.h"
+#endif
+
#include "vm/class.h"
#include "vm/classcache.h"
#include "vm/exceptions.h"
if (!link_class(class_java_lang_ThreadGroup))
return false;
+ if (!link_class(class_java_lang_VMSystem))
+ return false;
+
if (!link_class(class_java_lang_VMThread))
return false;
RT_TIMING_GET_TIME(time_start);
- if (!c) {
+ if (c == NULL) {
exceptions_throw_nullpointerexception();
return NULL;
}
-#if defined(ENABLE_THREADS)
- /* enter a monitor on the class */
-
- builtin_monitorenter((java_objectheader *) c);
-#endif
+ LOCK_MONITOR_ENTER(c);
/* maybe the class is already linked */
if (c->state & CLASS_LINKED) {
-#if defined(ENABLE_THREADS)
- builtin_monitorexit((java_objectheader *) c);
-#endif
+ LOCK_MONITOR_EXIT(c);
return c;
}
compilingtime_start();
#endif
-#if defined(ENABLE_THREADS)
- /* leave the monitor */
-
- builtin_monitorexit((java_objectheader *) c);
-#endif
+ LOCK_MONITOR_EXIT(c);
RT_TIMING_GET_TIME(time_end);
s4 vftbllength; /* vftbllength of current class */
s4 interfacetablelength; /* interface table length */
vftbl_t *v; /* vftbl of current class */
- s4 i,j; /* interface/method/field counter */
+ s4 i; /* interface/method/field counter */
arraydescriptor *arraydesc; /* descriptor for array classes */
#if defined(ENABLE_RT_TIMING)
struct timespec time_start, time_resolving, time_compute_vftbl,
time_abstract, time_compute_iftbl, time_fill_vftbl,
time_offsets, time_fill_iftbl, time_finalizer,
- time_exceptions, time_subclasses;
+ time_subclasses;
#endif
RT_TIMING_GET_TIME(time_start);
stub (all after the super class slots, because they are already
initialized). */
- for (; i < vftbllength; i++)
- v->table[i] = &asm_abstractmethoderror;
+ for (; i < vftbllength; i++) {
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+ if (opt_intrp)
+ v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
+ else
+# endif
+ v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
+#else
+ v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
+#endif
+ }
/* add method stubs into virtual function table */
for (i = 0; i < c->methodscount; i++) {
methodinfo *m = &(c->methods[i]);
+ assert(m->stubroutine == NULL);
+
+ /* Don't create a compiler stub for abstract methods as they
+ throw an AbstractMethodError with the default stub in the
+ vftbl. This entry is simply copied by sub-classes. */
+
if (m->flags & ACC_ABSTRACT)
continue;
- /* Methods in ABSTRACT classes from interfaces maybe already
- have a stubroutine. */
-
- if (m->stubroutine == NULL) {
#if defined(ENABLE_JIT)
# if defined(ENABLE_INTRP)
- if (opt_intrp)
- m->stubroutine = intrp_createcompilerstub(m);
- else
+ if (opt_intrp)
+ m->stubroutine = intrp_createcompilerstub(m);
+ else
#endif
- m->stubroutine = createcompilerstub(m);
+ m->stubroutine = createcompilerstub(m);
#else
- m->stubroutine = intrp_createcompilerstub(m);
+ m->stubroutine = intrp_createcompilerstub(m);
#endif
- }
- if (!(m->flags & ACC_STATIC))
- v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
+ /* static methods are not in the vftbl */
+
+ if (m->flags & ACC_STATIC)
+ continue;
+
+ /* insert the stubroutine into the vftbl */
+
+ v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
}
RT_TIMING_GET_TIME(time_fill_vftbl);
/* header structs like java_lang_Double must match the offsets */
/* of the Java fields (eg. java.lang.Double.value). */
#if defined(__I386__)
- c->instancesize = ALIGN(c->instancesize, 4);
+ c->instancesize = MEMORY_ALIGN(c->instancesize, 4);
#else
- c->instancesize = ALIGN(c->instancesize, dsize);
+ c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
#endif
f->offset = c->instancesize;
}
RT_TIMING_GET_TIME(time_finalizer);
- /* resolve exception class references */
-
- for (i = 0; i < c->methodscount; i++) {
- methodinfo *m = &(c->methods[i]);
-
- for (j = 0; j < m->exceptiontablelength; j++) {
- if (!m->exceptiontable[j].catchtype.any)
- continue;
- if (!resolve_classref_or_classinfo(NULL,
- m->exceptiontable[j].catchtype,
- resolveEager, true, false,
- &(m->exceptiontable[j].catchtype.cls)))
- return NULL;
- }
- }
- RT_TIMING_GET_TIME(time_exceptions);
-
/* final tasks */
linker_compute_subclasses(c);
RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
- RT_TIMING_TIME_DIFF(time_finalizer ,time_exceptions ,RT_TIMING_LINK_EXCEPTS);
- RT_TIMING_TIME_DIFF(time_exceptions ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
+ RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
/* just return c to show that we didn't had a problem */
/* If no method was found, insert the AbstractMethodError
stub. */
- v->interfacetable[-i][j] = &asm_abstractmethoderror;
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+ if (opt_intrp)
+ v->interfacetable[-i][j] =
+ (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
+ else
+# endif
+ v->interfacetable[-i][j] =
+ (methodptr) (ptrint) &asm_abstractmethoderror;
+#else
+ v->interfacetable[-i][j] =
+ (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
+#endif
foundmethod:
;