diff options
author | Andrew Haley <aph@redhat.com> | 2016-09-30 16:24:48 +0000 |
---|---|---|
committer | Andrew Haley <aph@gcc.gnu.org> | 2016-09-30 16:24:48 +0000 |
commit | 07b78716af6a9d7c9fd1e94d9baf94a52c873947 (patch) | |
tree | 3f22b3241c513ad168c8353805614ae1249410f4 /libjava/prims.cc | |
parent | eae993948bae8b788c53772bcb9217c063716f93 (diff) | |
download | gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.zip gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.tar.gz gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.tar.bz2 |
Makefile.def: Remove libjava.
2016-09-30 Andrew Haley <aph@redhat.com>
* Makefile.def: Remove libjava.
* Makefile.tpl: Likewise.
* Makefile.in: Regenerate.
* configure.ac: Likewise.
* configure: Likewise.
* gcc/java: Remove.
* libjava: Likewise.
From-SVN: r240662
Diffstat (limited to 'libjava/prims.cc')
-rw-r--r-- | libjava/prims.cc | 2038 |
1 files changed, 0 insertions, 2038 deletions
diff --git a/libjava/prims.cc b/libjava/prims.cc deleted file mode 100644 index 652cf5b..0000000 --- a/libjava/prims.cc +++ /dev/null @@ -1,2038 +0,0 @@ -// prims.cc - Code for core of runtime environment. - -/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation - - This file is part of libgcj. - -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ - -#include <config.h> -#include <platform.h> - -#include <stdlib.h> -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <signal.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <gcj/cni.h> -#include <jvm.h> -#include <java-signal.h> -#include <java-threads.h> -#include <java-interp.h> - -#ifdef ENABLE_JVMPI -#include <jvmpi.h> -#include <java/lang/ThreadGroup.h> -#endif - -#ifdef INTERPRETER -#include <jvmti.h> -#include "jvmti-int.h" -#endif - -#ifndef DISABLE_GETENV_PROPERTIES -#include <java-props.h> -#define PROCESS_GCJ_PROPERTIES process_gcj_properties() -#else -#define PROCESS_GCJ_PROPERTIES -#endif // DISABLE_GETENV_PROPERTIES - -#include <java/lang/Class.h> -#include <java/lang/ClassLoader.h> -#include <java/lang/Runtime.h> -#include <java/lang/String.h> -#include <java/lang/Thread.h> -#include <java/lang/ThreadGroup.h> -#include <java/lang/ArrayIndexOutOfBoundsException.h> -#include <java/lang/ArithmeticException.h> -#include <java/lang/ClassFormatError.h> -#include <java/lang/ClassNotFoundException.h> -#include <java/lang/InternalError.h> -#include <java/lang/NegativeArraySizeException.h> -#include <java/lang/NoClassDefFoundError.h> -#include <java/lang/NullPointerException.h> -#include <java/lang/OutOfMemoryError.h> -#include <java/lang/System.h> -#include <java/lang/VMClassLoader.h> -#include <java/lang/reflect/Modifier.h> -#include <java/io/PrintStream.h> -#include <java/lang/UnsatisfiedLinkError.h> -#include <java/lang/VirtualMachineError.h> -#include <gnu/gcj/runtime/ExtensionClassLoader.h> -#include <gnu/gcj/runtime/FinalizerThread.h> -#include <execution.h> - -#ifdef INTERPRETER -#include <gnu/classpath/jdwp/Jdwp.h> -#include <gnu/classpath/jdwp/VMVirtualMachine.h> -#endif // INTERPRETER - -#include <gnu/java/lang/MainThread.h> - -#ifdef USE_LTDL -#include <ltdl.h> -#endif - -// Execution engine for compiled code. -_Jv_CompiledEngine _Jv_soleCompiledEngine; - -// Execution engine for code compiled with -findirect-classes -_Jv_IndirectCompiledEngine _Jv_soleIndirectCompiledEngine; - -// We allocate a single OutOfMemoryError exception which we keep -// around for use if we run out of memory. -static java::lang::OutOfMemoryError *no_memory; - -// Number of bytes in largest array object we create. This could be -// increased to the largest size_t value, so long as the appropriate -// functions are changed to take a size_t argument instead of jint. -#define MAX_OBJECT_SIZE (((size_t)1<<31) - 1) - -// Properties set at compile time. -const char **_Jv_Compiler_Properties = NULL; -int _Jv_Properties_Count = 0; - -#ifndef DISABLE_GETENV_PROPERTIES -// Property key/value pairs. -property_pair *_Jv_Environment_Properties; -#endif - -// Stash the argv pointer to benefit native libraries that need it. -const char **_Jv_argv; -int _Jv_argc; - -// Debugging options -static bool remoteDebug = false; -#ifdef INTERPRETER -static char defaultJdwpOptions[] = ""; -static char *jdwpOptions = defaultJdwpOptions; - -// Typedefs for JVMTI agent functions. -typedef jint jvmti_agent_onload_func (JavaVM *vm, char *options, - void *reserved); -typedef jint jvmti_agent_onunload_func (JavaVM *vm); - -// JVMTI agent function pointers. -static jvmti_agent_onload_func *jvmti_agentonload = NULL; -static jvmti_agent_onunload_func *jvmti_agentonunload = NULL; -static char *jvmti_agent_opts; -#endif // INTERPRETER - -// Argument support. -int -_Jv_GetNbArgs (void) -{ - // _Jv_argc is 0 if not explicitly initialized. - return _Jv_argc; -} - -const char * -_Jv_GetSafeArg (int index) -{ - if (index >=0 && index < _Jv_GetNbArgs ()) - return _Jv_argv[index]; - else - return ""; -} - -void -_Jv_SetArgs (int argc, const char **argv) -{ - _Jv_argc = argc; - _Jv_argv = argv; -} - -#ifdef ENABLE_JVMPI -// Pointer to JVMPI notification functions. -void (*_Jv_JVMPI_Notify_OBJECT_ALLOC) (JVMPI_Event *event); -void (*_Jv_JVMPI_Notify_THREAD_START) (JVMPI_Event *event); -void (*_Jv_JVMPI_Notify_THREAD_END) (JVMPI_Event *event); -#endif - - -#if defined (HANDLE_SEGV) || defined(HANDLE_FPE) -/* Unblock a signal. Unless we do this, the signal may only be sent - once. */ -static void -unblock_signal (int signum __attribute__ ((__unused__))) -{ -#ifdef _POSIX_VERSION - sigset_t sigs; - - sigemptyset (&sigs); - sigaddset (&sigs, signum); - sigprocmask (SIG_UNBLOCK, &sigs, NULL); -#endif -} -#endif - -#ifdef HANDLE_SEGV -SIGNAL_HANDLER (catch_segv) -{ - unblock_signal (SIGSEGV); - MAKE_THROW_FRAME (nullp); - java::lang::NullPointerException *nullp - = new java::lang::NullPointerException; - throw nullp; -} -#endif - -#ifdef HANDLE_FPE -SIGNAL_HANDLER (catch_fpe) -{ - unblock_signal (SIGFPE); -#ifdef HANDLE_DIVIDE_OVERFLOW - HANDLE_DIVIDE_OVERFLOW; -#else - MAKE_THROW_FRAME (arithexception); -#endif - java::lang::ArithmeticException *arithexception - = new java::lang::ArithmeticException (JvNewStringLatin1 ("/ by zero")); - throw arithexception; -} -#endif - - -jboolean -_Jv_equalUtf8Consts (const Utf8Const* a, const Utf8Const *b) -{ - int len; - const _Jv_ushort *aptr, *bptr; - if (a == b) - return true; - if (a->hash != b->hash) - return false; - len = a->length; - if (b->length != len) - return false; - aptr = (const _Jv_ushort *)a->data; - bptr = (const _Jv_ushort *)b->data; - len = (len + 1) >> 1; - while (--len >= 0) - if (*aptr++ != *bptr++) - return false; - return true; -} - -/* True iff A is equal to STR. - HASH is STR->hashCode(). -*/ - -jboolean -_Jv_equal (Utf8Const* a, jstring str, jint hash) -{ - if (a->hash != (_Jv_ushort) hash) - return false; - jint len = str->length(); - jint i = 0; - jchar *sptr = _Jv_GetStringChars (str); - unsigned char* ptr = (unsigned char*) a->data; - unsigned char* limit = ptr + a->length; - for (;; i++, sptr++) - { - int ch = UTF8_GET (ptr, limit); - if (i == len) - return ch < 0; - if (ch != *sptr) - return false; - } - return true; -} - -/* Like _Jv_equal, but stop after N characters. */ -jboolean -_Jv_equaln (Utf8Const *a, jstring str, jint n) -{ - jint len = str->length(); - jint i = 0; - jchar *sptr = _Jv_GetStringChars (str); - unsigned char* ptr = (unsigned char*) a->data; - unsigned char* limit = ptr + a->length; - for (; n-- > 0; i++, sptr++) - { - int ch = UTF8_GET (ptr, limit); - if (i == len) - return ch < 0; - if (ch != *sptr) - return false; - } - return true; -} - -// Determines whether the given Utf8Const object contains -// a type which is primitive or some derived form of it, eg. -// an array or multi-dimensional array variant. -jboolean -_Jv_isPrimitiveOrDerived(const Utf8Const *a) -{ - unsigned char *aptr = (unsigned char *) a->data; - unsigned char *alimit = aptr + a->length; - int ac = UTF8_GET(aptr, alimit); - - // Skips any leading array marks. - while (ac == '[') - ac = UTF8_GET(aptr, alimit); - - // There should not be another character. This implies that - // the type name is only one character long. - if (UTF8_GET(aptr, alimit) == -1) - switch ( ac ) - { - case 'Z': - case 'B': - case 'C': - case 'S': - case 'I': - case 'J': - case 'F': - case 'D': - return true; - default: - break; - } - - return false; -} - -// Find out whether two _Jv_Utf8Const candidates contain the same -// classname. -// The method is written to handle the different formats of classnames. -// Eg. "Ljava/lang/Class;", "Ljava.lang.Class;", "java/lang/Class" and -// "java.lang.Class" will be seen as equal. -// Warning: This function is not smart enough to declare "Z" and "boolean" -// and similar cases as equal (and is not meant to be used this way)! -jboolean -_Jv_equalUtf8Classnames (const Utf8Const *a, const Utf8Const *b) -{ - // If the class name's length differs by two characters - // it is possible that we have candidates which are given - // in the two different formats ("Lp1/p2/cn;" vs. "p1/p2/cn") - switch (a->length - b->length) - { - case -2: - case 0: - case 2: - break; - default: - return false; - } - - unsigned char *aptr = (unsigned char *) a->data; - unsigned char *alimit = aptr + a->length; - unsigned char *bptr = (unsigned char *) b->data; - unsigned char *blimit = bptr + b->length; - - if (alimit[-1] == ';') - alimit--; - - if (blimit[-1] == ';') - blimit--; - - int ac = UTF8_GET(aptr, alimit); - int bc = UTF8_GET(bptr, blimit); - - // Checks whether both strings have the same amount of leading [ characters. - while (ac == '[') - { - if (bc == '[') - { - ac = UTF8_GET(aptr, alimit); - bc = UTF8_GET(bptr, blimit); - continue; - } - - return false; - } - - // Skips leading L character. - if (ac == 'L') - ac = UTF8_GET(aptr, alimit); - - if (bc == 'L') - bc = UTF8_GET(bptr, blimit); - - // Compares the remaining characters. - while (ac != -1 && bc != -1) - { - // Replaces package separating dots with slashes. - if (ac == '.') - ac = '/'; - - if (bc == '.') - bc = '/'; - - // Now classnames differ if there is at least one non-matching - // character. - if (ac != bc) - return false; - - ac = UTF8_GET(aptr, alimit); - bc = UTF8_GET(bptr, blimit); - } - - return (ac == bc); -} - -/* Count the number of Unicode chars encoded in a given Ut8 string. */ -int -_Jv_strLengthUtf8(const char* str, int len) -{ - unsigned char* ptr; - unsigned char* limit; - int str_length; - - ptr = (unsigned char*) str; - limit = ptr + len; - str_length = 0; - for (; ptr < limit; str_length++) - { - if (UTF8_GET (ptr, limit) < 0) - return (-1); - } - return (str_length); -} - -/* Calculate a hash value for a string encoded in Utf8 format. - * This returns the same hash value as specified or java.lang.String.hashCode. - */ -jint -_Jv_hashUtf8String (const char* str, int len) -{ - unsigned char* ptr = (unsigned char*) str; - unsigned char* limit = ptr + len; - jint hash = 0; - - for (; ptr < limit;) - { - int ch = UTF8_GET (ptr, limit); - /* Updated specification from - http://www.javasoft.com/docs/books/jls/clarify.html. */ - hash = (31 * hash) + ch; - } - return hash; -} - -void -_Jv_Utf8Const::init(const char *s, int len) -{ - ::memcpy (data, s, len); - data[len] = 0; - length = len; - hash = _Jv_hashUtf8String (s, len) & 0xFFFF; -} - -_Jv_Utf8Const * -_Jv_makeUtf8Const (const char* s, int len) -{ - if (len < 0) - len = strlen (s); - Utf8Const* m - = (Utf8Const*) _Jv_AllocBytes (_Jv_Utf8Const::space_needed(s, len)); - m->init(s, len); - return m; -} - -_Jv_Utf8Const * -_Jv_makeUtf8Const (jstring string) -{ - jint hash = string->hashCode (); - jint len = _Jv_GetStringUTFLength (string); - - Utf8Const* m = (Utf8Const*) - _Jv_AllocBytes (sizeof(Utf8Const) + len + 1); - - m->hash = hash; - m->length = len; - - _Jv_GetStringUTFRegion (string, 0, string->length (), m->data); - m->data[len] = 0; - - return m; -} - - - -#ifdef __GCJ_DEBUG -void -_Jv_Abort (const char *function, const char *file, int line, - const char *message) -#else -void -_Jv_Abort (const char *, const char *, int, const char *message) -#endif -{ -#ifdef __GCJ_DEBUG - fprintf (stderr, - "libgcj failure: %s\n in function %s, file %s, line %d\n", - message, function, file, line); -#else - fprintf (stderr, "libgcj failure: %s\n", message); -#endif - fflush (stderr); - abort (); -} - -static void -fail_on_finalization (jobject) -{ - JvFail ("object was finalized"); -} - -void -_Jv_GCWatch (jobject obj) -{ - _Jv_RegisterFinalizer (obj, fail_on_finalization); -} - -void -_Jv_ThrowBadArrayIndex(jint bad_index) -{ - throw new java::lang::ArrayIndexOutOfBoundsException - (java::lang::String::valueOf (bad_index)); -} - -void -_Jv_ThrowNullPointerException () -{ - throw new java::lang::NullPointerException; -} - -// Resolve an entry in the constant pool and return the target -// address. -void * -_Jv_ResolvePoolEntry (jclass this_class, jint index) -{ - _Jv_Constants *pool = &this_class->constants; - - if ((pool->tags[index] & JV_CONSTANT_ResolvedFlag) != 0) - return pool->data[index].field->u.addr; - - JvSynchronize sync (this_class); - return (_Jv_Linker::resolve_pool_entry (this_class, index)) - .field->u.addr; -} - - -// Explicitly throw a no memory exception. -// The collector calls this when it encounters an out-of-memory condition. -void _Jv_ThrowNoMemory() -{ - throw no_memory; -} - -#ifdef ENABLE_JVMPI -# define JVMPI_NOTIFY_ALLOC(klass,size,obj) \ - if (__builtin_expect (_Jv_JVMPI_Notify_OBJECT_ALLOC != 0, false)) \ - jvmpi_notify_alloc(klass,size,obj); -static void -jvmpi_notify_alloc(jclass klass, jint size, jobject obj) -{ - // Service JVMPI allocation request. - JVMPI_Event event; - - event.event_type = JVMPI_EVENT_OBJECT_ALLOC; - event.env_id = NULL; - event.u.obj_alloc.arena_id = 0; - event.u.obj_alloc.class_id = (jobjectID) klass; - event.u.obj_alloc.is_array = 0; - event.u.obj_alloc.size = size; - event.u.obj_alloc.obj_id = (jobjectID) obj; - - // FIXME: This doesn't look right for the Boehm GC. A GC may - // already be in progress. _Jv_DisableGC () doesn't wait for it. - // More importantly, I don't see the need for disabling GC, since we - // blatantly have a pointer to obj on our stack, ensuring that the - // object can't be collected. Even for a nonconservative collector, - // it appears to me that this must be true, since we are about to - // return obj. Isn't this whole approach way too intrusive for - // a useful profiling interface? - HB - _Jv_DisableGC (); - (*_Jv_JVMPI_Notify_OBJECT_ALLOC) (&event); - _Jv_EnableGC (); -} -#else /* !ENABLE_JVMPI */ -# define JVMPI_NOTIFY_ALLOC(klass,size,obj) /* do nothing */ -#endif - -// Allocate a new object of class KLASS. -// First a version that assumes that we have no finalizer, and that -// the class is already initialized. -// If we know that JVMPI is disabled, this can be replaced by a direct call -// to the allocator for the appropriate GC. -jobject -_Jv_AllocObjectNoInitNoFinalizer (jclass klass) -{ - jint size = klass->size (); - jobject obj = (jobject) _Jv_AllocObj (size, klass); - JVMPI_NOTIFY_ALLOC (klass, size, obj); - return obj; -} - -// And now a version that initializes if necessary. -jobject -_Jv_AllocObjectNoFinalizer (jclass klass) -{ - if (_Jv_IsPhantomClass(klass) ) - throw new java::lang::NoClassDefFoundError(klass->getName()); - - _Jv_InitClass (klass); - jint size = klass->size (); - jobject obj = (jobject) _Jv_AllocObj (size, klass); - JVMPI_NOTIFY_ALLOC (klass, size, obj); - return obj; -} - -// And now the general version that registers a finalizer if necessary. -jobject -_Jv_AllocObject (jclass klass) -{ - jobject obj = _Jv_AllocObjectNoFinalizer (klass); - - // We assume that the compiler only generates calls to this routine - // if there really is an interesting finalizer. - // Unfortunately, we still have to the dynamic test, since there may - // be cni calls to this routine. - // Note that on IA64 get_finalizer() returns the starting address of the - // function, not a function pointer. Thus this still works. - if (klass->vtable->get_finalizer () - != java::lang::Object::class$.vtable->get_finalizer ()) - _Jv_RegisterFinalizer (obj, _Jv_FinalizeObject); - return obj; -} - -// Allocate a String, including variable length storage. -jstring -_Jv_AllocString(jsize len) -{ - using namespace java::lang; - - jsize sz = sizeof(java::lang::String) + len * sizeof(jchar); - - // We assert that for strings allocated this way, the data field - // will always point to the object itself. Thus there is no reason - // for the garbage collector to scan any of it. - // Furthermore, we're about to overwrite the string data, so - // initialization of the object is not an issue. - - // String needs no initialization, and there is no finalizer, so - // we can go directly to the collector's allocator interface. - jstring obj = (jstring) _Jv_AllocPtrFreeObj(sz, &String::class$); - - obj->data = obj; - obj->boffset = sizeof(java::lang::String); - obj->count = len; - obj->cachedHashCode = 0; - - JVMPI_NOTIFY_ALLOC (&String::class$, sz, obj); - - return obj; -} - -// A version of the above that assumes the object contains no pointers, -// and requires no finalization. This can't happen if we need pointers -// to locks. -#ifdef JV_HASH_SYNCHRONIZATION -jobject -_Jv_AllocPtrFreeObject (jclass klass) -{ - _Jv_InitClass (klass); - jint size = klass->size (); - - jobject obj = (jobject) _Jv_AllocPtrFreeObj (size, klass); - - JVMPI_NOTIFY_ALLOC (klass, size, obj); - - return obj; -} -#endif /* JV_HASH_SYNCHRONIZATION */ - - -// Allocate a new array of Java objects. Each object is of type -// `elementClass'. `init' is used to initialize each slot in the -// array. -jobjectArray -_Jv_NewObjectArray (jsize count, jclass elementClass, jobject init) -{ - // Creating an array of an unresolved type is impossible. So we throw - // the NoClassDefFoundError. - if ( _Jv_IsPhantomClass(elementClass) ) - throw new java::lang::NoClassDefFoundError(elementClass->getName()); - - if (__builtin_expect (count < 0, false)) - throw new java::lang::NegativeArraySizeException; - - JvAssert (! elementClass->isPrimitive ()); - - // Ensure that elements pointer is properly aligned. - jobjectArray obj = NULL; - size_t size = (size_t) elements (obj); - // Check for overflow. - if (__builtin_expect ((size_t) count > - (MAX_OBJECT_SIZE - 1 - size) / sizeof (jobject), false)) - throw no_memory; - - size += count * sizeof (jobject); - - jclass klass = _Jv_GetArrayClass (elementClass, - elementClass->getClassLoaderInternal()); - - obj = (jobjectArray) _Jv_AllocArray (size, klass); - // Cast away const. - jsize *lp = const_cast<jsize *> (&obj->length); - *lp = count; - // We know the allocator returns zeroed memory. So don't bother - // zeroing it again. - if (init) - { - jobject *ptr = elements(obj); - while (--count >= 0) - *ptr++ = init; - } - return obj; -} - -// Allocate a new array of primitives. ELTYPE is the type of the -// element, COUNT is the size of the array. -jobject -_Jv_NewPrimArray (jclass eltype, jint count) -{ - int elsize = eltype->size(); - if (__builtin_expect (count < 0, false)) - throw new java::lang::NegativeArraySizeException; - - JvAssert (eltype->isPrimitive ()); - jobject dummy = NULL; - size_t size = (size_t) _Jv_GetArrayElementFromElementType (dummy, eltype); - - // Check for overflow. - if (__builtin_expect ((size_t) count > - (MAX_OBJECT_SIZE - size) / elsize, false)) - throw no_memory; - - jclass klass = _Jv_GetArrayClass (eltype, 0); - -# ifdef JV_HASH_SYNCHRONIZATION - // Since the vtable is always statically allocated, - // these are completely pointerfree! Make sure the GC doesn't touch them. - __JArray *arr = - (__JArray*) _Jv_AllocPtrFreeObj (size + elsize * count, klass); - memset((char *)arr + size, 0, elsize * count); -# else - __JArray *arr = (__JArray*) _Jv_AllocObj (size + elsize * count, klass); - // Note that we assume we are given zeroed memory by the allocator. -# endif - // Cast away const. - jsize *lp = const_cast<jsize *> (&arr->length); - *lp = count; - - return arr; -} - -jobject -_Jv_NewArray (jint type, jint size) -{ - switch (type) - { - case 4: return JvNewBooleanArray (size); - case 5: return JvNewCharArray (size); - case 6: return JvNewFloatArray (size); - case 7: return JvNewDoubleArray (size); - case 8: return JvNewByteArray (size); - case 9: return JvNewShortArray (size); - case 10: return JvNewIntArray (size); - case 11: return JvNewLongArray (size); - } - throw new java::lang::InternalError - (JvNewStringLatin1 ("invalid type code in _Jv_NewArray")); -} - -// Allocate a possibly multi-dimensional array but don't check that -// any array length is <0. -static jobject -_Jv_NewMultiArrayUnchecked (jclass type, jint dimensions, jint *sizes) -{ - JvAssert (type->isArray()); - jclass element_type = type->getComponentType(); - jobject result; - if (element_type->isPrimitive()) - result = _Jv_NewPrimArray (element_type, sizes[0]); - else - result = _Jv_NewObjectArray (sizes[0], element_type, NULL); - - if (dimensions > 1) - { - JvAssert (! element_type->isPrimitive()); - JvAssert (element_type->isArray()); - jobject *contents = elements ((jobjectArray) result); - for (int i = 0; i < sizes[0]; ++i) - contents[i] = _Jv_NewMultiArrayUnchecked (element_type, dimensions - 1, - sizes + 1); - } - - return result; -} - -jobject -_Jv_NewMultiArray (jclass type, jint dimensions, jint *sizes) -{ - for (int i = 0; i < dimensions; ++i) - if (sizes[i] < 0) - throw new java::lang::NegativeArraySizeException; - - return _Jv_NewMultiArrayUnchecked (type, dimensions, sizes); -} - -jobject -_Jv_NewMultiArray (jclass array_type, jint dimensions, ...) -{ - // Creating an array of an unresolved type is impossible. So we throw - // the NoClassDefFoundError. - if (_Jv_IsPhantomClass(array_type)) - throw new java::lang::NoClassDefFoundError(array_type->getName()); - - va_list args; - jint sizes[dimensions]; - va_start (args, dimensions); - for (int i = 0; i < dimensions; ++i) - { - jint size = va_arg (args, jint); - if (size < 0) - throw new java::lang::NegativeArraySizeException; - sizes[i] = size; - } - va_end (args); - - return _Jv_NewMultiArrayUnchecked (array_type, dimensions, sizes); -} - - - -// Ensure 8-byte alignment, for hash synchronization. -#define DECLARE_PRIM_TYPE(NAME) \ - java::lang::Class _Jv_##NAME##Class __attribute__ ((aligned (8))); - -DECLARE_PRIM_TYPE(byte) -DECLARE_PRIM_TYPE(short) -DECLARE_PRIM_TYPE(int) -DECLARE_PRIM_TYPE(long) -DECLARE_PRIM_TYPE(boolean) -DECLARE_PRIM_TYPE(char) -DECLARE_PRIM_TYPE(float) -DECLARE_PRIM_TYPE(double) -DECLARE_PRIM_TYPE(void) - -void -_Jv_InitPrimClass (jclass cl, const char *cname, char sig, int len) -{ - using namespace java::lang::reflect; - - // We must set the vtable for the class; the Java constructor - // doesn't do this. - (*(_Jv_VTable **) cl) = java::lang::Class::class$.vtable; - - // Initialize the fields we care about. We do this in the same - // order they are declared in Class.h. - cl->name = _Jv_makeUtf8Const ((char *) cname, -1); - cl->accflags = Modifier::PUBLIC | Modifier::FINAL | Modifier::ABSTRACT; - cl->method_count = sig; - cl->size_in_bytes = len; - cl->vtable = JV_PRIMITIVE_VTABLE; - cl->state = JV_STATE_DONE; - cl->depth = -1; -} - -jclass -_Jv_FindClassFromSignature (char *sig, java::lang::ClassLoader *loader, - char **endp) -{ - // First count arrays. - int array_count = 0; - while (*sig == '[') - { - ++sig; - ++array_count; - } - - jclass result = NULL; - switch (*sig) - { - case 'B': - result = JvPrimClass (byte); - break; - case 'S': - result = JvPrimClass (short); - break; - case 'I': - result = JvPrimClass (int); - break; - case 'J': - result = JvPrimClass (long); - break; - case 'Z': - result = JvPrimClass (boolean); - break; - case 'C': - result = JvPrimClass (char); - break; - case 'F': - result = JvPrimClass (float); - break; - case 'D': - result = JvPrimClass (double); - break; - case 'V': - result = JvPrimClass (void); - break; - case 'L': - { - char *save = ++sig; - while (*sig && *sig != ';') - ++sig; - // Do nothing if signature appears to be malformed. - if (*sig == ';') - { - _Jv_Utf8Const *name = _Jv_makeUtf8Const (save, sig - save); - result = _Jv_FindClass (name, loader); - } - break; - } - default: - // Do nothing -- bad signature. - break; - } - - if (endp) - { - // Not really the "end", but the last valid character that we - // looked at. - *endp = sig; - } - - if (! result) - return NULL; - - // Find arrays. - while (array_count-- > 0) - result = _Jv_GetArrayClass (result, loader); - return result; -} - - -jclass -_Jv_FindClassFromSignatureNoException (char *sig, java::lang::ClassLoader *loader, - char **endp) -{ - jclass klass; - - try - { - klass = _Jv_FindClassFromSignature(sig, loader, endp); - } - catch (java::lang::NoClassDefFoundError *ncdfe) - { - return NULL; - } - catch (java::lang::ClassNotFoundException *cnfe) - { - return NULL; - } - - return klass; -} - -JArray<jstring> * -JvConvertArgv (int argc, const char **argv) -{ - if (argc < 0) - argc = 0; - jobjectArray ar = JvNewObjectArray(argc, &java::lang::String::class$, NULL); - jobject *ptr = elements(ar); - jbyteArray bytes = NULL; - for (int i = 0; i < argc; i++) - { - const char *arg = argv[i]; - int len = strlen (arg); - if (bytes == NULL || bytes->length < len) - bytes = JvNewByteArray (len); - jbyte *bytePtr = elements (bytes); - // We assume jbyte == char. - memcpy (bytePtr, arg, len); - - // Now convert using the default encoding. - *ptr++ = new java::lang::String (bytes, 0, len); - } - return (JArray<jstring>*) ar; -} - -// FIXME: These variables are static so that they will be -// automatically scanned by the Boehm collector. This is needed -// because with qthreads the collector won't scan the initial stack -- -// it will only scan the qthreads stacks. - -// Command line arguments. -static JArray<jstring> *arg_vec; - -// The primary thread. -static java::lang::Thread *main_thread; - -#ifndef DISABLE_GETENV_PROPERTIES - -#define c_isspace(c) (memchr (" \t\n\r\v\f", c, 6) != NULL) - -static char * -next_property_key (char *s, size_t *length) -{ - size_t l = 0; - - JvAssert (s); - - // Skip over whitespace - while (c_isspace (*s)) - s++; - - // If we've reached the end, return NULL. Also return NULL if for - // some reason we've come across a malformed property string. - if (*s == 0 - || *s == ':' - || *s == '=') - return NULL; - - // Determine the length of the property key. - while (s[l] != 0 - && ! c_isspace (s[l]) - && s[l] != ':' - && s[l] != '=') - { - if (s[l] == '\\' - && s[l+1] != 0) - l++; - l++; - } - - *length = l; - - return s; -} - -static char * -next_property_value (char *s, size_t *length) -{ - size_t l = 0; - - JvAssert (s); - - while (c_isspace (*s)) - s++; - - if (*s == ':' - || *s == '=') - s++; - - while (c_isspace (*s)) - s++; - - // Determine the length of the property value. - while (s[l] != 0 - && ! c_isspace (s[l]) - && s[l] != ':' - && s[l] != '=') - { - if (s[l] == '\\' - && s[l+1] != 0) - l += 2; - else - l++; - } - - *length = l; - - return s; -} - -static void -process_gcj_properties () -{ - char *props = getenv("GCJ_PROPERTIES"); - - if (NULL == props) - return; - - // Later on we will write \0s into this string. It is simplest to - // just duplicate it here. - props = strdup (props); - - char *p = props; - size_t length; - size_t property_count = 0; - - // Whip through props quickly in order to count the number of - // property values. - while (p && (p = next_property_key (p, &length))) - { - // Skip to the end of the key - p += length; - - p = next_property_value (p, &length); - if (p) - p += length; - - property_count++; - } - - // Allocate an array of property value/key pairs. - _Jv_Environment_Properties = - (property_pair *) malloc (sizeof(property_pair) - * (property_count + 1)); - - // Go through the properties again, initializing _Jv_Properties - // along the way. - p = props; - property_count = 0; - while (p && (p = next_property_key (p, &length))) - { - _Jv_Environment_Properties[property_count].key = p; - _Jv_Environment_Properties[property_count].key_length = length; - - // Skip to the end of the key - p += length; - - p = next_property_value (p, &length); - - _Jv_Environment_Properties[property_count].value = p; - _Jv_Environment_Properties[property_count].value_length = length; - - if (p) - p += length; - - property_count++; - } - memset ((void *) &_Jv_Environment_Properties[property_count], - 0, sizeof (property_pair)); - - // Null terminate the strings. - for (property_pair *prop = &_Jv_Environment_Properties[0]; - prop->key != NULL; - prop++) - { - prop->key[prop->key_length] = 0; - prop->value[prop->value_length] = 0; - } -} -#endif // DISABLE_GETENV_PROPERTIES - -namespace gcj -{ - _Jv_Utf8Const *void_signature; - _Jv_Utf8Const *clinit_name; - _Jv_Utf8Const *init_name; - _Jv_Utf8Const *finit_name; - - bool runtimeInitialized = false; - - // When true, print debugging information about class loading. - bool verbose_class_flag; - - // When true, enable the bytecode verifier and BC-ABI type verification. - bool verifyClasses = true; - - // Thread stack size specified by the -Xss runtime argument. - size_t stack_size = 0; - - // Start time of the VM - jlong startTime = 0; - - // Arguments passed to the VM - JArray<jstring>* vmArgs; - - // Currently loaded classes - jint loadedClasses = 0; - - // Unloaded classes - jlong unloadedClasses = 0; -} - -// We accept all non-standard options accepted by Sun's java command, -// for compatibility with existing application launch scripts. -static jint -parse_x_arg (char* option_string) -{ - if (strlen (option_string) <= 0) - return -1; - - if (! strcmp (option_string, "int")) - { - // FIXME: this should cause the vm to never load shared objects - } - else if (! strcmp (option_string, "mixed")) - { - // FIXME: allow interpreted and native code - } - else if (! strcmp (option_string, "batch")) - { - // FIXME: disable background JIT'ing - } - else if (! strcmp (option_string, "debug")) - { - remoteDebug = true; - } -#ifdef INTERPRETER - else if (! strncmp (option_string, "runjdwp:", 8)) - { - if (strlen (option_string) > 8) - jdwpOptions = &option_string[8]; - else - { - fprintf (stderr, - "libgcj: argument required for JDWP options"); - return -1; - } - } -#endif // INTERPRETER - else if (! strncmp (option_string, "bootclasspath:", 14)) - { - // FIXME: add a parse_bootclasspath_arg function - } - else if (! strncmp (option_string, "bootclasspath/a:", 16)) - { - } - else if (! strncmp (option_string, "bootclasspath/p:", 16)) - { - } - else if (! strcmp (option_string, "check:jni")) - { - // FIXME: enable strict JNI checking - } - else if (! strcmp (option_string, "future")) - { - // FIXME: enable strict class file format checks - } - else if (! strcmp (option_string, "noclassgc")) - { - // FIXME: disable garbage collection for classes - } - else if (! strcmp (option_string, "incgc")) - { - // FIXME: incremental garbage collection - } - else if (! strncmp (option_string, "loggc:", 6)) - { - if (option_string[6] == '\0') - { - fprintf (stderr, - "libgcj: filename argument expected for loggc option\n"); - return -1; - } - // FIXME: set gc logging filename - } - else if (! strncmp (option_string, "ms", 2)) - { - // FIXME: ignore this option until PR 20699 is fixed. - // _Jv_SetInitialHeapSize (option_string + 2); - } - else if (! strncmp (option_string, "mx", 2)) - _Jv_SetMaximumHeapSize (option_string + 2); - else if (! strcmp (option_string, "prof")) - { - // FIXME: enable profiling of program running in vm - } - else if (! strncmp (option_string, "runhprof:", 9)) - { - // FIXME: enable specific type of vm profiling. add a - // parse_runhprof_arg function - } - else if (! strcmp (option_string, "rs")) - { - // FIXME: reduced system signal usage. disable thread dumps, - // only terminate in response to user-initiated calls, - // e.g. System.exit() - } - else if (! strncmp (option_string, "ss", 2)) - { - _Jv_SetStackSize (option_string + 2); - } - else if (! strcmp (option_string, "X:+UseAltSigs")) - { - // FIXME: use signals other than SIGUSR1 and SIGUSR2 - } - else if (! strcmp (option_string, "share:off")) - { - // FIXME: don't share class data - } - else if (! strcmp (option_string, "share:auto")) - { - // FIXME: share class data where possible - } - else if (! strcmp (option_string, "share:on")) - { - // FIXME: fail if impossible to share class data - } - else - { - // Unrecognized. - return -1; - } - return 0; -} - -static jint -parse_verbose_args (char* option_string, - bool ignore_unrecognized) -{ - size_t len = sizeof ("-verbose") - 1; - - if (strlen (option_string) < len) - return -1; - - if (option_string[len] == ':' - && option_string[len + 1] != '\0') - { - char* verbose_args = option_string + len + 1; - - do - { - if (! strncmp (verbose_args, - "gc", sizeof ("gc") - 1)) - { - if (verbose_args[sizeof ("gc") - 1] == '\0' - || verbose_args[sizeof ("gc") - 1] == ',') - { - // FIXME: we should add functions to boehm-gc that - // toggle GC_print_stats, GC_PRINT_ADDRESS_MAP and - // GC_print_back_height. - verbose_args += sizeof ("gc") - 1; - } - else - { - verbose_arg_err: - fprintf (stderr, "libgcj: unknown verbose option: %s\n", - option_string); - return -1; - } - } - else if (! strncmp (verbose_args, - "class", - sizeof ("class") - 1)) - { - if (verbose_args[sizeof ("class") - 1] == '\0' - || verbose_args[sizeof ("class") - 1] == ',') - { - gcj::verbose_class_flag = true; - verbose_args += sizeof ("class") - 1; - } - else - goto verbose_arg_err; - } - else if (! strncmp (verbose_args, "jni", - sizeof ("jni") - 1)) - { - if (verbose_args[sizeof ("jni") - 1] == '\0' - || verbose_args[sizeof ("jni") - 1] == ',') - { - // FIXME: enable JNI messages. - verbose_args += sizeof ("jni") - 1; - } - else - goto verbose_arg_err; - } - else if (ignore_unrecognized - && verbose_args[0] == 'X') - { - // ignore unrecognized non-standard verbose option - while (verbose_args[0] != '\0' - && verbose_args[0] != ',') - verbose_args++; - } - else if (verbose_args[0] == ',') - { - verbose_args++; - } - else - goto verbose_arg_err; - - if (verbose_args[0] == ',') - verbose_args++; - } - while (verbose_args[0] != '\0'); - } - else if (option_string[len] == 'g' - && option_string[len + 1] == 'c' - && option_string[len + 2] == '\0') - { - // FIXME: we should add functions to boehm-gc that - // toggle GC_print_stats, GC_PRINT_ADDRESS_MAP and - // GC_print_back_height. - return 0; - } - else if (option_string[len] == '\0') - { - gcj::verbose_class_flag = true; - return 0; - } - else - { - // unrecognized option beginning with -verbose - return -1; - } - return 0; -} - -#ifdef INTERPRETER -// This function loads the agent functions for JVMTI from the library indicated -// by name. It returns a negative value on failure, the value of which -// indicates where ltdl failed, it also prints an error message. -static jint -load_jvmti_agent (const char *name) -{ -#ifdef USE_LTDL - if (lt_dlinit ()) - { - fprintf (stderr, - "libgcj: Error in ltdl init while loading agent library.\n"); - return -1; - } - - lt_dlhandle lib = lt_dlopenext (name); - if (!lib) - { - fprintf (stderr, - "libgcj: Error opening agent library.\n"); - return -2; - } - - if (lib) - { - jvmti_agentonload - = (jvmti_agent_onload_func *) lt_dlsym (lib, "Agent_OnLoad"); - - if (!jvmti_agentonload) - { - fprintf (stderr, - "libgcj: Error finding agent function in library %s.\n", - name); - lt_dlclose (lib); - lib = NULL; - return -4; - } - else - { - jvmti_agentonunload - = (jvmti_agent_onunload_func *) lt_dlsym (lib, "Agent_OnUnload"); - - return 0; - } - } - else - { - fprintf (stderr, "libgcj: Library %s not found in library path.\n", name); - return -3; - } - -#endif /* USE_LTDL */ - - // If LTDL cannot be used, return an error code indicating this. - return -99; -} -#endif // INTERPRETER - -static jint -parse_init_args (JvVMInitArgs* vm_args) -{ - // if _Jv_Compiler_Properties is non-NULL then it needs to be - // re-allocated dynamically. - if (_Jv_Compiler_Properties) - { - const char** props = _Jv_Compiler_Properties; - _Jv_Compiler_Properties = NULL; - - for (int i = 0; props[i]; i++) - { - _Jv_Compiler_Properties = (const char**) _Jv_Realloc - (_Jv_Compiler_Properties, - (_Jv_Properties_Count + 1) * sizeof (const char*)); - _Jv_Compiler_Properties[_Jv_Properties_Count++] = props[i]; - } - } - - if (vm_args == NULL) - return 0; - - for (int i = 0; i < vm_args->nOptions; ++i) - { - char* option_string = vm_args->options[i].optionString; - - if (! strcmp (option_string, "vfprintf") - || ! strcmp (option_string, "exit") - || ! strcmp (option_string, "abort")) - { - // FIXME: we are required to recognize these, but for - // now we don't handle them in any way. - continue; - } - else if (! strncmp (option_string, - "-verbose", sizeof ("-verbose") - 1)) - { - jint result = parse_verbose_args (option_string, - vm_args->ignoreUnrecognized); - if (result < 0) - return result; - } - else if (! strncmp (option_string, "-D", 2)) - { - _Jv_Compiler_Properties = (const char**) _Jv_Realloc - (_Jv_Compiler_Properties, - (_Jv_Properties_Count + 1) * sizeof (char*)); - - _Jv_Compiler_Properties[_Jv_Properties_Count++] = - strdup (option_string + 2); - - continue; - } -#ifdef INTERPRETER - else if (! strncmp (option_string, "-agentlib", sizeof ("-agentlib") - 1)) - { - char *strPtr; - - if (strlen(option_string) > (sizeof ("-agentlib:") - 1)) - strPtr = &option_string[sizeof ("-agentlib:") - 1]; - else - { - fprintf (stderr, - "libgcj: Malformed agentlib argument %s: expected lib name\n", - option_string); - return -1; - } - - // These are optional arguments to pass to the agent library. - jvmti_agent_opts = strchr (strPtr, '='); - - if (! strncmp (strPtr, "jdwp", 4)) - { - // We want to run JDWP here so set the correct variables. - remoteDebug = true; - jdwpOptions = ++jvmti_agent_opts; - } - else - { - jint nameLength; - - if (jvmti_agent_opts == NULL) - nameLength = strlen (strPtr); - else - { - nameLength = jvmti_agent_opts - strPtr; - jvmti_agent_opts++; - } - - char lib_name[nameLength + 3 + 1]; - strcpy (lib_name, "lib"); - strncat (lib_name, strPtr, nameLength); - - jint result = load_jvmti_agent (lib_name); - - if (result < 0) - { - return -1; - } - - // Mark JVMTI active - JVMTI::enabled = true; - } - - continue; - } - else if (! strncmp (option_string, "-agentpath:", - sizeof ("-agentpath:") - 1)) - { - char *strPtr; - - if (strlen(option_string) > 10) - strPtr = &option_string[10]; - else - { - fprintf (stderr, - "libgcj: Malformed agentlib argument %s: expected lib path\n", - option_string); - return -1; - } - - // These are optional arguments to pass to the agent library. - jvmti_agent_opts = strchr (strPtr, '='); - - jint nameLength; - - if (jvmti_agent_opts == NULL) - nameLength = strlen (strPtr); - else - { - nameLength = jvmti_agent_opts - strPtr; - jvmti_agent_opts++; - } - - char lib_name[nameLength + 3 + 1]; - strcpy (lib_name, "lib"); - strncat (lib_name, strPtr, nameLength); - jint result = load_jvmti_agent (strPtr); - - if (result < 0) - { - return -1; - } - - // Mark JVMTI active - JVMTI::enabled = true; - continue; - } -#endif // INTERPRETER - else - { - int r = -1; - if (option_string[0] == '_') - r = parse_x_arg (option_string + 1); - else if (! strncmp (option_string, "-X", 2)) - r = parse_x_arg (option_string + 2); - - if (r == -1 && ! vm_args->ignoreUnrecognized) - { - fprintf (stderr, "libgcj: unknown option: %s\n", option_string); - return -1; - } - } - } - return 0; -} - -jint -_Jv_CreateJavaVM (JvVMInitArgs* vm_args) -{ - using namespace gcj; - - if (runtimeInitialized) - return -1; - - runtimeInitialized = true; - startTime = _Jv_platform_gettimeofday(); - - jint result = parse_init_args (vm_args); - if (result < 0) - return -1; - - PROCESS_GCJ_PROPERTIES; - - /* Threads must be initialized before the GC, so that it inherits the - signal mask. */ - _Jv_InitThreads (); - _Jv_InitGC (); - _Jv_InitializeSyncMutex (); - -#ifdef INTERPRETER - _Jv_InitInterpreter (); -#endif - -#ifdef HANDLE_SEGV - INIT_SEGV; -#endif - -#ifdef HANDLE_FPE - INIT_FPE; -#endif - - /* Initialize Utf8 constants declared in jvm.h. */ - void_signature = _Jv_makeUtf8Const ("()V", 3); - clinit_name = _Jv_makeUtf8Const ("<clinit>", 8); - init_name = _Jv_makeUtf8Const ("<init>", 6); - finit_name = _Jv_makeUtf8Const ("finit$", 6); - - /* Initialize built-in classes to represent primitive TYPEs. */ - _Jv_InitPrimClass (&_Jv_byteClass, "byte", 'B', 1); - _Jv_InitPrimClass (&_Jv_shortClass, "short", 'S', 2); - _Jv_InitPrimClass (&_Jv_intClass, "int", 'I', 4); - _Jv_InitPrimClass (&_Jv_longClass, "long", 'J', 8); - _Jv_InitPrimClass (&_Jv_booleanClass, "boolean", 'Z', 1); - _Jv_InitPrimClass (&_Jv_charClass, "char", 'C', 2); - _Jv_InitPrimClass (&_Jv_floatClass, "float", 'F', 4); - _Jv_InitPrimClass (&_Jv_doubleClass, "double", 'D', 8); - _Jv_InitPrimClass (&_Jv_voidClass, "void", 'V', 0); - - // We have to initialize this fairly early, to avoid circular class - // initialization. In particular we want to start the - // initialization of ClassLoader before we start the initialization - // of VMClassLoader. - _Jv_InitClass (&java::lang::ClassLoader::class$); - - // Set up the system class loader and the bootstrap class loader. - gnu::gcj::runtime::ExtensionClassLoader::initialize(); - java::lang::VMClassLoader::initialize(JvNewStringLatin1(TOOLEXECLIBDIR)); - - _Jv_RegisterBootstrapPackages(); - - no_memory = new java::lang::OutOfMemoryError; - -#ifdef USE_LTDL - LTDL_SET_PRELOADED_SYMBOLS (); -#endif - - _Jv_platform_initialize (); - - _Jv_JNI_Init (); - -#ifdef INTERPRETER - _Jv_JVMTI_Init (); -#endif - - _Jv_GCInitializeFinalizers (&::gnu::gcj::runtime::FinalizerThread::finalizerReady); - - // Start the GC finalizer thread. A VirtualMachineError can be - // thrown by the runtime if, say, threads aren't available. - try - { - using namespace gnu::gcj::runtime; - FinalizerThread *ft = new FinalizerThread (); - ft->start (); - } - catch (java::lang::VirtualMachineError *ignore) - { - } - - runtimeInitialized = true; - - return 0; -} - -void -_Jv_RunMain (JvVMInitArgs *vm_args, jclass klass, const char *name, int argc, - const char **argv, bool is_jar) -{ -#ifndef DISABLE_MAIN_ARGS - _Jv_SetArgs (argc, argv); -#endif - - java::lang::Runtime *runtime = NULL; - - try - { - if (_Jv_CreateJavaVM (vm_args) < 0) - { - fprintf (stderr, "libgcj: couldn't create virtual machine\n"); - exit (1); - } - - if (vm_args == NULL) - gcj::vmArgs = JvConvertArgv(0, NULL); - else - { - const char* vmArgs[vm_args->nOptions]; - const char** vmPtr = vmArgs; - struct _Jv_VMOption* optionPtr = vm_args->options; - for (int i = 0; i < vm_args->nOptions; ++i) - *vmPtr++ = (*optionPtr++).optionString; - gcj::vmArgs = JvConvertArgv(vm_args->nOptions, vmArgs); - } - - // Get the Runtime here. We want to initialize it before searching - // for `main'; that way it will be set up if `main' is a JNI method. - runtime = java::lang::Runtime::getRuntime (); - -#ifdef DISABLE_MAIN_ARGS - arg_vec = JvConvertArgv (0, 0); -#else - arg_vec = JvConvertArgv (argc - 1, argv + 1); -#endif - - using namespace gnu::java::lang; - if (klass) - main_thread = new MainThread (klass, arg_vec); - else - main_thread = new MainThread (JvNewStringUTF (name), - arg_vec, is_jar); - _Jv_AttachCurrentThread (main_thread); - -#ifdef INTERPRETER - // Start JVMTI if an agent function has been found. - if (jvmti_agentonload) - (*jvmti_agentonload) (_Jv_GetJavaVM (), jvmti_agent_opts, NULL); - - // Start JDWP - if (remoteDebug) - { - using namespace gnu::classpath::jdwp; - VMVirtualMachine::initialize (); - Jdwp *jdwp = new Jdwp (); - jdwp->setDaemon (true); - jdwp->configure (JvNewStringLatin1 (jdwpOptions)); - jdwp->start (); - - // Wait for JDWP to initialize and start - jdwp->join (); - } - // Send VMInit - if (JVMTI_REQUESTED_EVENT (VMInit)) - _Jv_JVMTI_PostEvent (JVMTI_EVENT_VM_INIT, main_thread); -#endif // INTERPRETER - } - catch (java::lang::Throwable *t) - { - java::lang::System::err->println (JvNewStringLatin1 - ("Exception during runtime initialization")); - t->printStackTrace(); - if (runtime) - java::lang::Runtime::exitNoChecksAccessor (1); - // In case the runtime creation failed. - ::exit (1); - } - - _Jv_ThreadRun (main_thread); - -#ifdef INTERPRETER - // Send VMDeath - if (JVMTI_REQUESTED_EVENT (VMDeath)) - { - java::lang::Thread *thread = java::lang::Thread::currentThread (); - JNIEnv *jni_env = _Jv_GetCurrentJNIEnv (); - _Jv_JVMTI_PostEvent (JVMTI_EVENT_VM_DEATH, thread, jni_env); - } - - // Run JVMTI AgentOnUnload if it exists and an agent is loaded. - if (jvmti_agentonunload) - (*jvmti_agentonunload) (_Jv_GetJavaVM ()); -#endif // INTERPRETER - - // If we got here then something went wrong, as MainThread is not - // supposed to terminate. - ::exit (1); -} - -void -_Jv_RunMain (jclass klass, const char *name, int argc, const char **argv, - bool is_jar) -{ - _Jv_RunMain (NULL, klass, name, argc, argv, is_jar); -} - -void -JvRunMain (jclass klass, int argc, const char **argv) -{ - _Jv_RunMain (klass, NULL, argc, argv, false); -} - -void -JvRunMainName (const char *name, int argc, const char **argv) -{ - _Jv_RunMain (NULL, name, argc, argv, false); -} - - - -// Parse a string and return a heap size. -static size_t -parse_memory_size (const char *spec) -{ - char *end; - unsigned long val = strtoul (spec, &end, 10); - if (*end == 'k' || *end == 'K') - val *= 1024; - else if (*end == 'm' || *end == 'M') - val *= 1048576; - return (size_t) val; -} - -// Set the initial heap size. This might be ignored by the GC layer. -// This must be called before _Jv_RunMain. -void -_Jv_SetInitialHeapSize (const char *arg) -{ - size_t size = parse_memory_size (arg); - _Jv_GCSetInitialHeapSize (size); -} - -// Set the maximum heap size. This might be ignored by the GC layer. -// This must be called before _Jv_RunMain. -void -_Jv_SetMaximumHeapSize (const char *arg) -{ - size_t size = parse_memory_size (arg); - _Jv_GCSetMaximumHeapSize (size); -} - -void -_Jv_SetStackSize (const char *arg) -{ - size_t size = parse_memory_size (arg); - gcj::stack_size = size; -} - -void * -_Jv_Malloc (jsize size) -{ - if (__builtin_expect (size == 0, false)) - size = 1; - void *ptr = malloc ((size_t) size); - if (__builtin_expect (ptr == NULL, false)) - throw no_memory; - return ptr; -} - -void * -_Jv_Realloc (void *ptr, jsize size) -{ - if (__builtin_expect (size == 0, false)) - size = 1; - ptr = realloc (ptr, (size_t) size); - if (__builtin_expect (ptr == NULL, false)) - throw no_memory; - return ptr; -} - -void * -_Jv_MallocUnchecked (jsize size) -{ - if (__builtin_expect (size == 0, false)) - size = 1; - return malloc ((size_t) size); -} - -void -_Jv_Free (void* ptr) -{ - return free (ptr); -} - - - -// In theory, these routines can be #ifdef'd away on machines which -// support divide overflow signals. However, we never know if some -// code might have been compiled with "-fuse-divide-subroutine", so we -// always include them in libgcj. - -jint -_Jv_divI (jint dividend, jint divisor) -{ - if (__builtin_expect (divisor == 0, false)) - { - java::lang::ArithmeticException *arithexception - = new java::lang::ArithmeticException (JvNewStringLatin1 ("/ by zero")); - throw arithexception; - } - - if (dividend == (jint) 0x80000000L && divisor == -1) - return dividend; - - return dividend / divisor; -} - -jint -_Jv_remI (jint dividend, jint divisor) -{ - if (__builtin_expect (divisor == 0, false)) - { - java::lang::ArithmeticException *arithexception - = new java::lang::ArithmeticException (JvNewStringLatin1 ("/ by zero")); - throw arithexception; - } - - if (dividend == (jint) 0x80000000L && divisor == -1) - return 0; - - return dividend % divisor; -} - -jlong -_Jv_divJ (jlong dividend, jlong divisor) -{ - if (__builtin_expect (divisor == 0, false)) - { - java::lang::ArithmeticException *arithexception - = new java::lang::ArithmeticException (JvNewStringLatin1 ("/ by zero")); - throw arithexception; - } - - if (dividend == (jlong) 0x8000000000000000LL && divisor == -1) - return dividend; - - return dividend / divisor; -} - -jlong -_Jv_remJ (jlong dividend, jlong divisor) -{ - if (__builtin_expect (divisor == 0, false)) - { - java::lang::ArithmeticException *arithexception - = new java::lang::ArithmeticException (JvNewStringLatin1 ("/ by zero")); - throw arithexception; - } - - if (dividend == (jlong) 0x8000000000000000LL && divisor == -1) - return 0; - - return dividend % divisor; -} - - - -// Return true if SELF_KLASS can access a field or method in -// OTHER_KLASS. The field or method's access flags are specified in -// FLAGS. -jboolean -_Jv_CheckAccess (jclass self_klass, jclass other_klass, jint flags) -{ - using namespace java::lang::reflect; - return ((self_klass == other_klass) - || ((flags & Modifier::PUBLIC) != 0) - || (((flags & Modifier::PROTECTED) != 0) - && _Jv_IsAssignableFromSlow (self_klass, other_klass)) - || (((flags & Modifier::PRIVATE) == 0) - && _Jv_ClassNameSamePackage (self_klass->name, - other_klass->name))); -} - -// Prepend GCJ_VERSIONED_LIBDIR to a module search path stored in a C -// char array, if the path is not already prefixed by -// GCJ_VERSIONED_LIBDIR. Return a newly JvMalloc'd char buffer. The -// result should be freed using JvFree. -char* -_Jv_PrependVersionedLibdir (char* libpath) -{ - char* retval = 0; - - if (libpath && libpath[0] != '\0') - { - if (! strncmp (libpath, - GCJ_VERSIONED_LIBDIR, - sizeof (GCJ_VERSIONED_LIBDIR) - 1)) - { - // LD_LIBRARY_PATH is already prefixed with - // GCJ_VERSIONED_LIBDIR. - retval = (char*) _Jv_Malloc (strlen (libpath) + 1); - strcpy (retval, libpath); - } - else - { - // LD_LIBRARY_PATH is not prefixed with - // GCJ_VERSIONED_LIBDIR. - char path_sep[2]; - path_sep[0] = (char) _Jv_platform_path_separator; - path_sep[1] = '\0'; - jsize total = ((sizeof (GCJ_VERSIONED_LIBDIR) - 1) - + 1 /* path separator */ + strlen (libpath) + 1); - retval = (char*) _Jv_Malloc (total); - strcpy (retval, GCJ_VERSIONED_LIBDIR); - strcat (retval, path_sep); - strcat (retval, libpath); - } - } - else - { - // LD_LIBRARY_PATH was not specified or is empty. - retval = (char*) _Jv_Malloc (sizeof (GCJ_VERSIONED_LIBDIR)); - strcpy (retval, GCJ_VERSIONED_LIBDIR); - } - - return retval; -} |