Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: linker.c 8343 2007-08-17 21:39:32Z michi $
-
*/
#include "config.h"
#include <assert.h>
+#include <stdint.h>
#include "vm/types.h"
/* linker_init *****************************************************************
- Initializes the linker subsystem.
+ Initializes the linker subsystem and links classes required for the
+ primitive table.
*******************************************************************************/
-bool linker_init(void)
+void linker_preinit(void)
{
/* 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 (OFFSET(dummy_alignment_long_t, l) != 4)
- vm_abort("linker_init: long alignment is different from what assumed: %d != %d",
+ vm_abort("linker_preinit: long alignment is different from what assumed: %d != %d",
OFFSET(dummy_alignment_long_t, l), 4);
if (OFFSET(dummy_alignment_double_t, d) != 4)
- vm_abort("linker_init: double alignment is different from what assumed: %d != %d",
+ vm_abort("linker_preinit: double alignment is different from what assumed: %d != %d",
OFFSET(dummy_alignment_double_t, d), 4);
#else
if (OFFSET(dummy_alignment_long_t, l) != 8)
- vm_abort("linker_init: long alignment is different from what assumed: %d != %d",
+ vm_abort("linker_preinit: long alignment is different from what assumed: %d != %d",
OFFSET(dummy_alignment_long_t, l), 8);
if (OFFSET(dummy_alignment_double_t, d) != 8)
- vm_abort("linker_init: double alignment is different from what assumed: %d != %d",
+ vm_abort("linker_preinit: double alignment is different from what assumed: %d != %d",
OFFSET(dummy_alignment_double_t, d), 8);
#endif
- /* reset interface index */
+ /* Reset interface index. */
interfaceindex = 0;
LOCK_INIT_OBJECT_LOCK(linker_classrenumber_lock);
#endif
- /* 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 */
+ /* Link the most basic classes. */
- if (!link_class(class_java_lang_Class))
- return false;
+ if (!link_class(class_java_lang_Object))
+ vm_abort("linker_preinit: linking java/lang/Object failed");
- /* now set the header.vftbl of all classes which were created
- before java.lang.Class was linked */
+#if defined(ENABLE_JAVASE)
+ if (!link_class(class_java_lang_Cloneable))
+ vm_abort("linker_preinit: linking java/lang/Cloneable failed");
- class_postset_header_vftbl();
+ if (!link_class(class_java_io_Serializable))
+ vm_abort("linker_preinit: linking java/io/Serializable failed");
+#endif
+}
- /* link important system classes */
+/* linker_init *****************************************************************
- if (!link_class(class_java_lang_Object))
- return false;
+ Links all classes required in the VM.
- if (!link_class(class_java_lang_String))
- return false;
+*******************************************************************************/
-#if defined(ENABLE_JAVASE)
- if (!link_class(class_java_lang_Cloneable))
- return false;
+void linker_init(void)
+{
+ /* 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. */
- if (!link_class(class_java_io_Serializable))
- return false;
-#endif
+ if (!link_class(class_java_lang_Class))
+ vm_abort("linker_init: linking java/lang/Class failed");
+
+ /* Now set the header.vftbl of all classes which were created
+ before java.lang.Class was linked. */
+
+ class_postset_header_vftbl();
- /* link classes for wrapping primitive types */
+ /* Link primitive-type wrapping classes. */
#if defined(ENABLE_JAVASE)
if (!link_class(class_java_lang_Void))
- return false;
+ vm_abort("linker_init: linking failed");
#endif
if (!link_class(class_java_lang_Boolean))
- return false;
+ vm_abort("linker_init: linking failed");
if (!link_class(class_java_lang_Byte))
- return false;
+ vm_abort("linker_init: linking failed");
if (!link_class(class_java_lang_Character))
- return false;
+ vm_abort("linker_init: linking failed");
if (!link_class(class_java_lang_Short))
- return false;
+ vm_abort("linker_init: linking failed");
if (!link_class(class_java_lang_Integer))
- return false;
+ vm_abort("linker_init: linking failed");
if (!link_class(class_java_lang_Long))
- return false;
+ vm_abort("linker_init: linking failed");
if (!link_class(class_java_lang_Float))
- return false;
+ vm_abort("linker_init: linking failed");
if (!link_class(class_java_lang_Double))
- return false;
+ vm_abort("linker_init: linking failed");
+ /* Link important system classes. */
- /* load some other important classes */
+ if (!link_class(class_java_lang_String))
+ vm_abort("linker_init: linking java/lang/String failed");
#if defined(ENABLE_JAVASE)
if (!link_class(class_java_lang_ClassLoader))
- return false;
+ vm_abort("linker_init: linking failed");
if (!link_class(class_java_lang_SecurityManager))
- return false;
+ vm_abort("linker_init: linking failed");
#endif
if (!link_class(class_java_lang_System))
- return false;
+ vm_abort("linker_init: linking failed");
if (!link_class(class_java_lang_Thread))
- return false;
+ vm_abort("linker_init: linking failed");
#if defined(ENABLE_JAVASE)
if (!link_class(class_java_lang_ThreadGroup))
- return false;
+ vm_abort("linker_init: linking failed");
#endif
#if defined(WITH_CLASSPATH_GNU)
if (!link_class(class_java_lang_VMSystem))
- return false;
+ vm_abort("linker_init: linking failed");
if (!link_class(class_java_lang_VMThread))
- return false;
+ vm_abort("linker_init: linking failed");
#endif
#if defined(ENABLE_JAVASE)
if (!link_class(class_java_lang_StackTraceElement))
- return false;
+ vm_abort("linker_init: linking failed");
if (!link_class(class_java_lang_reflect_Constructor))
- return false;
+ vm_abort("linker_init: linking failed");
if (!link_class(class_java_lang_reflect_Field))
- return false;
+ vm_abort("linker_init: linking failed");
if (!link_class(class_java_lang_reflect_Method))
- return false;
+ vm_abort("linker_init: linking failed");
if (!link_class(class_java_security_PrivilegedAction))
- return false;
+ vm_abort("linker_init: linking failed");
if (!link_class(class_java_util_Vector))
- return false;
+ vm_abort("linker_init: linking failed");
# if defined(WITH_CLASSPATH_SUN)
if (!link_class(class_sun_reflect_MagicAccessorImpl))
- return false;
+ vm_abort("linker_init: linking failed");
# endif
if (!link_class(arrayclass_java_lang_Object))
- return false;
+ vm_abort("linker_init: linking failed");
#endif
pseudo_class_Arraystub->super.cls = class_java_lang_Object;
#if defined(ENABLE_JAVASE)
+
pseudo_class_Arraystub->interfacescount = 2;
pseudo_class_Arraystub->interfaces = MNEW(classref_or_classinfo, 2);
pseudo_class_Arraystub->interfaces[0].cls = class_java_lang_Cloneable;
pseudo_class_Arraystub->interfaces[1].cls = class_java_io_Serializable;
+
#elif defined(ENABLE_JAVAME_CLDC1_1)
+
pseudo_class_Arraystub->interfacescount = 0;
pseudo_class_Arraystub->interfaces = NULL;
+
+#else
+# error unknown Java configuration
#endif
- if (!classcache_store_unique(pseudo_class_Arraystub)) {
- log_text("could not cache pseudo_class_Arraystub");
- assert(0);
- }
+ if (!classcache_store_unique(pseudo_class_Arraystub))
+ vm_abort("linker_init: could not cache pseudo_class_Arraystub");
if (!link_class(pseudo_class_Arraystub))
- return false;
+ vm_abort("linker_init: linking pseudo_class_Arraystub failed");
/* pseudo class representing the null type */
vm_abort("linker_init: could not cache pseudo_class_Null");
if (!link_class(pseudo_class_Null))
- return false;
+ vm_abort("linker_init: linking failed");
/* pseudo class representing new uninitialized objects */
java/lang/String). */
stringtable_update();
-
- return true;
}
LOCK_MONITOR_ENTER(c);
- /* maybe the class is already linked */
+ /* Maybe the class is currently linking or is already linked.*/
- if (c->state & CLASS_LINKED) {
+ if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
LOCK_MONITOR_EXIT(c);
return c;
r = link_class_intern(c);
- /* if return value is NULL, we had a problem and the class is not linked */
+ /* If return value is NULL, we had a problem and the class is not
+ linked. */
- if (!r)
+ if (r == NULL)
c->state &= ~CLASS_LINKING;
#if defined(ENABLE_STATISTICS)
RT_TIMING_GET_TIME(time_start);
- /* the class is already linked */
-
- if (c->state & CLASS_LINKED)
- return c;
-
#if !defined(NDEBUG)
if (linkverbose)
log_message_class("Linking class: ", c);
/* XXX should this be a specific exception? */
assert(c->state & CLASS_LOADED);
+ /* This is check in link_class. */
+
+ assert(!(c->state & CLASS_LINKED));
+
/* cache the self-reference of this class */
/* we do this for cases where the defining loader of the class */
/* has not yet been recorded as an initiating loader for the class */
c->finalizer = NULL;
- } else {
- /* resolve super class */
+ }
+ else {
+ /* Resolve super class. */
- if ((super = resolve_classref_or_classinfo_eager(c->super, true)) == NULL)
+ super = resolve_classref_or_classinfo_eager(c->super, true);
+
+ if (super == NULL)
return NULL;
c->super.cls = super;
- /* detect circularity */
+ /* Detect circularity. */
if (super == c) {
exceptions_throw_classcircularityerror(c);