示例#1
0
文件: thread.c 项目: Liam1206/jamvm
char classlibInitJavaThread(Thread *thread, Object *jlthread, Object *name,
                            Object *group, char is_daemon, int priority) {

    INST_DATA(jlthread, Thread*, eetop_offset) = thread;
    INST_DATA(jlthread, int, daemon_offset) = is_daemon;
    INST_DATA(jlthread, int, priority_offset) = priority;

    if(name == NULL)
        executeMethod(jlthread, init_mb_no_name, group, NULL);
    else
        executeMethod(jlthread, init_mb_with_name, group, name);

    return !exceptionOccurred();
}
示例#2
0
文件: thread.c 项目: Liam1206/jamvm
Object *classlibThreadPreInit(Class *thread_class, Class *thrdGrp_class) {
    MethodBlock *system_init_mb, *main_init_mb;
    FieldBlock *thread_status_fb, *eetop_fb;
    Object *system, *main, *main_name;

    init_mb_with_name = findMethod(thread_class, SYMBOL(object_init),
                           SYMBOL(_java_lang_ThreadGroup_java_lang_String__V));

    init_mb_no_name = findMethod(thread_class, SYMBOL(object_init),
                         SYMBOL(_java_lang_ThreadGroup_java_lang_Runnable__V));

    thread_status_fb = findField(thread_class, SYMBOL(threadStatus),
                                               SYMBOL(I));

    eetop_fb = findField(thread_class, SYMBOL(eetop), SYMBOL(J));

    system_init_mb = findMethod(thrdGrp_class, SYMBOL(object_init),
                                               SYMBOL(___V));

    main_init_mb = findMethod(thrdGrp_class, SYMBOL(object_init),
                           SYMBOL(_java_lang_ThreadGroup_java_lang_String__V));

    if(init_mb_with_name   == NULL || init_mb_no_name == NULL ||
          system_init_mb   == NULL || main_init_mb    == NULL ||
          thread_status_fb == NULL || eetop_fb        == NULL)
        return NULL;

    CLASS_CB(thread_class)->flags |= JTHREAD;

    thread_status_offset = thread_status_fb->u.offset;
    eetop_offset = eetop_fb->u.offset;

    if((system = allocObject(thrdGrp_class)) == NULL)
        return NULL;

    executeMethod(system, system_init_mb);
    if(exceptionOccurred())
        return NULL;

    if((main = allocObject(thrdGrp_class)) == NULL ||
       (main_name = Cstr2String("main")) == NULL)
        return NULL;

    executeMethod(main, main_init_mb, system, main_name);
    if(exceptionOccurred())
        return NULL;

    return main;
}
示例#3
0
Object *initJavaThread(Thread *thread, char is_daemon, const char *name) {
    Object *vmthread, *jlthread, *thread_name = NULL;

    /* Create the java.lang.Thread object and the VMThread */
    if((vmthread = allocObject(vmthread_class)) == NULL ||
       (jlthread = allocObject(thread_class)) == NULL)
        return NULL;

    //thread->ee->thread = jlthread;
    thread->thread = jlthread;
    INST_DATA(vmthread)[vmData_offset] = (uintptr_t)thread;
    INST_DATA(vmthread)[thread_offset] = (uintptr_t)jlthread;

    /* Create the string for the thread name.  If null is specified
       the initialiser method will generate a name of the form Thread-X */
    if(name != NULL && (thread_name = Cstr2String(name)) == NULL)
        return NULL;

    /* Call the initialiser method -- this is for use by threads
       created or attached by the VM "outside" of Java */
    DummyFrame dummy;
    executeMethod(&dummy, jlthread, init_mb, vmthread, thread_name, NORM_PRIORITY, is_daemon);

    /* Add thread to thread ID map hash table. */
    addThreadToHash(thread);

    return jlthread;
}
示例#4
0
文件: instance.c 项目: ahua/java
/*
 * Execute the ANEWARRAY instruction
 */
void op_anewarray() {
    Ref type = resolve(u16(1), ID_TYPE);
    if (type == NULL) { return; } // rollback, gc done
    Ref arrayType = getRef(type, TYPE_ARRAY_TYPE);

    // resolve array type
    if (arrayType == NULL) {
        Ref target = getRef(core, OBJECT_TYPE);
        Ref method = getRef(core, CORE_RESOLVE_METHOD);
        executeMethod(target, method, 0);
        return; // rollback
    }

    // allocate space
    int length = peekInt(); // don't pop yet in case gc runs
    int numWords = ARRAY_DATA + length;
    Ref array = allocate(numWords, HEADER_OBJECT_ARRAY);
    if (array == NULL) { return; } // rollback, gc done
    popInt(); // pop length

    // initialise array object and push on stack
    int hash = (char*) array - (char*) core;
    setInt(array, OBJECT_HASHCODE, hash);
    setRef(array, OBJECT_TYPE, arrayType);
    setInt(array, ARRAY_LENGTH, length);
    pushRef(array);
    pc += 3;
}
示例#5
0
void *threadStart(void *arg) {
    Thread *thread = (Thread *)arg;
    //Object *jThread = thread->ee->thread;
    Object *jThread = thread->thread;

    /* Parent thread created thread with suspension disabled.
       This is inherited so we need to enable */
    enableSuspend(thread);

    /* Complete initialisation of the thread structure, create the thread
       stack and add the thread to the thread list */
    initThread(thread, INST_DATA(jThread)[daemon_offset], &thread);

    /* Add thread to thread ID map hash table. */
    addThreadToHash(thread);

    /* Execute the thread's run method */
    DummyFrame dummy;
    executeMethod(&dummy, jThread, CLASS_CB(jThread->classobj)->method_table[run_mtbl_idx]);

    /* Run has completed.  Detach the thread from the VM and exit */
    detachThread(thread);

    TRACE("Thread 0x%x id: %d exited\n", thread, thread->id);
    return NULL;
}
示例#6
0
Thread *attachThread(char *name, char is_daemon, void *stack_base, Thread *thread, Object *group) {
    Object *java_thread;

    /* Create the ExecEnv for the thread */
//     ExecEnv *ee = (ExecEnv*)sysMalloc(sizeof(ExecEnv));
//     memset(ee, 0, sizeof(ExecEnv));

    thread->tid = pthread_self();
    //thread->ee = ee;

    /* Complete initialisation of the thread structure, create the thread
       stack and add the thread to the thread list */
    initThread(thread, is_daemon, stack_base);

    /* Initialise the Java-level thread objects representing this thread */
    if((java_thread = initJavaThread(thread, is_daemon, name)) == NULL)
        return NULL;

    /* Initialiser doesn't handle the thread group */
    INST_DATA(java_thread)[group_offset] = (uintptr_t)group;
    DummyFrame dummy;
    executeMethod(&dummy, group, addThread_mb, java_thread);

    /* We're now attached to the VM...*/
    TRACE("Thread 0x%x id: %d attached\n", thread, thread->id);
    return thread;
}
示例#7
0
// função classInitialization
void	classInitialization(CLASS_DATA * cd, JVM * jvm, THREAD * thread){
/*	A IMPLEMENTAR
Initialization of a class consists of two steps:

Initializing the class's direct superclass (if any), if the direct superclass hasn't already been initialized
Executing the class's class initialization method, if it has one
*/
	
	if((cd->classfile)->super_class){
		cp_info	* cp_aux = (cd->classfile)->constant_pool + (cd->classfile)->super_class - 1;
		cp_aux = (cd->classfile)->constant_pool + cp_aux->u.Class.name_index - 1;
		char	* super_class_name = cp_aux->u.Utf8.bytes;
/*		super_class_name[cp_aux->u.Utf8.length] = '\0';*/
/*		printf("Super class:\t");*/
/*		PrintConstantUtf8(cp_aux, stdout);*/
/*		puts("");*/
/*		if(strcmp(super_class_name, "java/lang/Object")){*/
			CLASS_DATA	* cd_super;
/*			if(!(cd_super = getSuperClass(cd->classfile, jvm))){*/
			if(!(cd_super = getClass(cp_aux, jvm))){
				classLoading(strcat(super_class_name, ".class"), &cd_super, cd, jvm);
			}
			classLinking(cd_super, jvm);
			classInitialization(cd_super, jvm, thread);
/*		}*/
	}
/*	executeMethod("<init>", cd, jvm, thread, cd);*/
	executeMethod("<clinit>", cd, jvm, thread, cd);	
}// fim da função classInitialization
// Method ID = 8
void EMLiveMonitor::pushMetric( Report::ptr_t report )
{
  EXEParamList paramsList;

  paramsList.push_back( report );
    
  executeMethod( 8, paramsList );
}
示例#9
0
文件: excep.c 项目: OPSF/uClinux
void signalChainedExceptionClass(Class *exception, char *message, Object *cause) {
    Object *exp = allocObject(exception);
    Object *str = message == NULL ? NULL : Cstr2String(message);
    MethodBlock *init = lookupMethod(exception, SYMBOL(object_init),
                                                SYMBOL(_java_lang_String__V));
    if(exp && init) {
        executeMethod(exp, init, str);

        if(cause && !exceptionOccurred()) {
            MethodBlock *mb = lookupMethod(exception, SYMBOL(initCause),
                                           SYMBOL(_java_lang_Throwable__java_lang_Throwable));
            if(mb)
                executeMethod(exp, mb, cause);
        }
        setException(exp);
    }
}
示例#10
0
文件: Test.cpp 项目: nnen/cppapp
TestResult TestRef::debug()
{
	TestResult result;
	
	setUp();
	executeMethod();
	tearDown();
	
	return result;
}
示例#11
0
文件: interpreter.c 项目: ahua/java
/*
 * Retrieve the constant pool entry at the given index. If the id of the
 * entry does not match the given id call the resolve method of the core
 * object and return null. The code in the core object will replace
 * the placeholder entry with the resolved object.
 */
Ref resolve(int index, int id) {
    Ref entry = getPoolEntry(index);
    if (getInt(entry, ENTRY_ID) != id) {
        Ref type = getRef(core, OBJECT_TYPE);
        Ref method = getRef(core, CORE_RESOLVE_METHOD);
        executeMethod(type, method, 0);
        return NULL;
    }
    return entry;
}
示例#12
0
文件: invoke.c 项目: ahua/java
/*
 * Execute the INVOKESPECIAL instruction
 */
void op_invokespecial() {
    Ref method = resolve(u16(1), ID_METHOD);
    if (method == NULL) { return; } // rollback, gc done

    // check the target object
    Int argcount = getInt(method, METHOD_ARG_COUNT);
    Ref target = stack[argcount - 1].value.r;
    if (target == NULL) { throwException(CORE_THROW_NULL_POINTER); }

    // execute the method
    else { executeMethod(target, method, 3); }
}
示例#13
0
文件: jni.c 项目: Liam1206/jamvm
Object *classlibNewDirectByteBuffer(void *addr, long long capacity) {
    Object *buff, *rawdata;

    if((buff = allocObject(buffImpl_class)) != NULL &&
            (rawdata = allocObject(rawdata_class)) != NULL) {

        INST_DATA(rawdata, void*, rawdata_offset) = addr;
        executeMethod(buff, buffImpl_init_mb, NULL, rawdata, (int)capacity,
                      (int)capacity, 0);
    }

    return buff;
}
//invokespecial
int op_invokespecial( unsigned char **opCode, StackFrame *stack, SimpleConstantPool *p ) {
    u2 method_index ;
    unsigned char tmp[2];
    tmp[0] = opCode[0][1];
    tmp[1] = opCode[0][2];
    method_index = tmp[0] << 8 | tmp[1];
#if SIMPLE_JVM_DEBUG
    printf("call method_index %d\n", method_index);
#endif
    *opCode = *opCode + 3;
    if ( method_index < simpleMethodPool.method_used ) {
        MethodInfo *method = &simpleMethodPool.method[method_index];
        executeMethod( method, &stackFrame, &simpleConstantPool );
    }
    return 0;
}
示例#15
0
文件: invoke.c 项目: ahua/java
/*
 * Execute the INVOKEVIRTUAL instruction
 */
void op_invokevirtual() {
    Ref entry = resolve(u16(1), ID_METHOD);
    if (entry == NULL) { return; } // rollback, gc done

    // check the target object
    int argcount = getInt(entry, METHOD_ARG_COUNT);
    Ref target = stack[argcount - 1].value.r;
    if (target == NULL) { throwException(CORE_THROW_NULL_POINTER); }

    // resolve and execute the method
    else {
        Ref type = getRef(target, OBJECT_TYPE);
        Ref name = getRef(entry, ENTRY_NAME);
        Ref desc = getRef(entry, ENTRY_DESCRIPTOR);
        Ref resolved = resolveMethod(type, name, desc);
        executeMethod(target, resolved, 3);
    }
}
示例#16
0
文件: excep.c 项目: OPSF/uClinux
void printException() {
    ExecEnv *ee = getExecEnv();
    Object *exception = ee->exception;

    if(exception != NULL) {
        MethodBlock *mb = lookupMethod(exception->class, SYMBOL(printStackTrace),
                                                         SYMBOL(___V));
        clearException();
        executeMethod(exception, mb);

        /* If we're really low on memory we might have been able to throw
         * OutOfMemory, but then been unable to print any part of it!  In
         * this case the VM just seems to stop... */
        if(ee->exception) {
            jam_fprintf(stderr, "Exception occurred while printing exception (%s)...\n",
                            CLASS_CB(ee->exception->class)->name);
            jam_fprintf(stderr, "Original exception was %s\n", CLASS_CB(exception->class)->name);
        }
示例#17
0
文件: invoke.c 项目: ahua/java
/*
 * Execute the INVOKEINTERFACE instruction
 */
void op_invokeinterface() {
    Ref entry = resolve(u16(1), ID_METHOD);
    if (entry == NULL) { return; } // rollback, gc done

    // check for null pointer
    Int argcount = getInt(entry, METHOD_ARG_COUNT);
    Ref object = stack[argcount - 1].value.r;
    if (object == NULL) {
        throwException(CORE_THROW_NULL_POINTER);
        return;
    }

    // resolve and execute
    Ref desc = getRef(entry, ENTRY_DESCRIPTOR);
    Ref name = getRef(entry, ENTRY_NAME);
    Ref type = getRef(object, OBJECT_TYPE);
    Ref method = resolveMethod(type, name, desc);
    executeMethod(object, method, 5);
}
示例#18
0
文件: Test.cpp 项目: nnen/cppapp
TestResult TestRef::run()
{
	TestResult result;
	
	setUp();
	
	try {
		executeMethod();
	} catch (TestResult &r) {
		result = r;
	} catch (std::exception &e) {
		result = TestResult(e);
	} catch (...) {
		result = TestResult(false, "", 0, "", "unknown exception");
	}
	
	result.expectedFailure = getExpectFailure();
	
	tearDown();
	
	return result;
}
示例#19
0
// função jvmStart
void	jvmStart(char * class_filename, int num_args, char * args[]){
/*
https://docs.oracle.com/javase/specs/jvms/se6/html/Concepts.doc.html#16491
https://docs.oracle.com/javase/specs/jvms/se6/html/Concepts.doc.html#19042
*/	
	JVM	* jvm;
	jvm = (JVM *) malloc(sizeof(JVM));
	jvm->method_area = NULL;
	jvm->threads = NULL;
	jvm->heap = (HEAP_AREA *) malloc(sizeof(HEAP_AREA));
	
	CLASS_DATA	* main_class_data;
	
	
/*	puts("DEBUG:\tCLASS LOADING\n");*/
	classLoading(class_filename, &main_class_data, NULL, jvm);
/*	puts("DEBUG:\tCLASS LINKING\n");*/
	classLinking(main_class_data, jvm);
	
	// INICIA THREAD PRINCIPAL
	THREAD		* main_thread = (THREAD *) malloc(sizeof(THREAD));
	main_thread->program_counter = NULL;
	main_thread->jvm_stack = NULL;
	main_thread->prox = NULL;
	jvm->threads = main_thread;
	
/*	puts("DEBUG:\tCLASS INITIALIZATION\n");*/
	classInitialization(main_class_data, jvm, main_thread);
	
	if(main_class_data->modifiers & ACC_ABSTRACT){
		puts("ERROR: method 'main' not find.");
		exit(EXIT_FAILURE);
	}
	executeMethod("main", main_class_data, jvm, main_thread, main_class_data);
	
	classUnloading(main_class_data, jvm);
	jvmExit(jvm);
}// fim da função jvmStart
// User methods --------------------------------------------------------------
// Method ID = 7
void EMLiveMonitor::notifyReadyToPush()
{
  EXEParamList emptyParams;

  executeMethod( 7, emptyParams );
}
示例#21
0
文件: invoke.c 项目: ahua/java
/*
 * Execute the specified native method. Return true if the method
 * is executed, false if it is rolled back for garbage collection.
 */
int executeNativeMethod(Ref target, Ref method, int offset) {
    int magic = getInt(method, METHOD_MAGIC);
    if (magic == 0) {
        printf("Native method not supported\n");
        debugTrace();
        exit(1);
    }
    switch (magic) {
        // print a debug message
        case MAGIC_RUNTIME_CORE_DEBUG:
            debugLine(popRef());
            pc += offset;
            break;

        // execute the given static method
        case MAGIC_RUNTIME_CORE_EXECUTE_STATIC:
            {
                Ref staticMethod = popRef();
                if (staticMethod  == NULL) {
                    throwException(CORE_THROW_NULL_POINTER);
                    return;
                }
                Ref owner = getRef(staticMethod, ENTRY_OWNER);
                if (!executeMethod(owner, staticMethod, offset)) {
                    // restore stack if rolled back for gc
                    pushRef(staticMethod); 
                }
            }
            break;

        // return the current frame
        case MAGIC_RUNTIME_FRAME_CURRENT:
            pushRef(frame);
            pc += offset;
            break;

        // return the core object
        case MAGIC_RUNTIME_CORE_GET:
            pushRef(core);
            pc += offset;
            break;

        // create a statics object
        case MAGIC_RUNTIME_STATICS_CREATE:
            {
                // allocate space for statics object
                Ref type = popRef();
                Int numStaticFields = getInt(type, TYPE_STATIC_FIELD_COUNT);
                Int numWords = STATICS_FIELDS + numStaticFields;
                Ref statics = allocate(numWords, HEADER_STATIC_FIELDS);
                if (statics == NULL) {
                    pushRef(type); // restore stack
                    return; // rollback, gc done
                }

                // initialise statics object and set in type object
                int hash = (char*) statics - (char*) core;
                setInt(statics, OBJECT_HASHCODE, hash);
                Ref staticsType = getRef(core, CORE_STATICS_TYPE);
                setRef(statics, OBJECT_TYPE, staticsType);
                Ref map = getRef(type, TYPE_STATIC_MAP);
                setRef(statics, STATICS_MAP, map);
                setRef(type, TYPE_STATICS, statics);
            }
            pc += offset;
            break;

        // read the type from a class
        case MAGIC_RUNTIME_CORE_GET_TYPE:
            {
                Ref class = popRef();
                // type is first field in class...
                Ref type = getRef(class, OBJECT_FIELDS);
                pushRef(type);
            }
            pc += offset;
            break;

        // put system to sleep to avoid wasting processor time while idle
        case MAGIC_RUNTIME_IDLE_SLEEP:
            idleSleep();
            pc += offset;
            break;

        // return the currently executing thread
        case MAGIC_RUNTIME_THREAD_CURRENT:
            pushRef(thread);
            pc += offset;
            break;

        // start a new thread
        case MAGIC_RUNTIME_THREAD_START_HOOK:
            startNewThread(offset);
            break;

        // return an object's class
        case MAGIC_JAVA_OBJECT_GET_CLASS:
            {
                Ref obj = popRef();
                Ref type = getRef(obj, OBJECT_TYPE);
                Ref peer = getRef(type, TYPE_PEER);
                pushRef(peer);
            }
            pc += offset;
            break;

        // set system output stream
        case MAGIC_JAVA_SYSTEM_SET_OUT:
            {
                Ref arg = popRef();
                Ref type = getRef(method, ENTRY_OWNER);
                Ref statics = getRef(type, TYPE_STATICS);
                setRef(statics, STATICS_FIELDS + SYSTEM_OUT, arg);
            }
            pc += offset;
            break;

        // set system error stream
        case MAGIC_JAVA_SYSTEM_SET_ERR:
            {
                Ref arg = popRef();
                Ref type = getRef(method, ENTRY_OWNER);
                Ref statics = getRef(type, TYPE_STATICS);
                setRef(statics, STATICS_FIELDS + SYSTEM_ERR, arg);
            }
            pc += offset;
            break;

        // set system input stream
        case MAGIC_JAVA_SYSTEM_SET_IN:
            {
                Ref arg = popRef();
                Ref type = getRef(method, ENTRY_OWNER);
                Ref statics = getRef(type, TYPE_STATICS);
                setRef(statics, STATICS_FIELDS + SYSTEM_IN, arg);
            }
            pc += offset;
            break;

        // read an ascii character from the console
        case MAGIC_TEST_READ_FROM_CONSOLE:
            {
                char c = readFromConsole();
                pushInt(c);
            }
            pc += offset;
            break;
            
        // write an ascii character to the console
        case MAGIC_TEST_WRITE_TO_CONSOLE:
            {
                char c = popInt() & 0xFF;
                printf("%c", c);
            }
            pc += offset;
            break;

        // read a byte from the floppy drive
        case MAGIC_TEST_READ_FROM_FLOPPY:
            {
                Int pos = popInt();
                pushInt(readFromFloppy(pos));
            }
            pc += offset;
            break;
			
        // magic id not recognised
        default:
            printf("Invalid magic method id: %d\n", magic);
            exit(1);
            break;
    }
}
示例#22
0
文件: exceptions.c 项目: ahua/java
/*
 * This method is used whenever the system needs to throw an exception
 * while trying to execute a java bytecode instruction. The given method
 * offset indicates a field of the core object referring to a static
 * method which throws the desired exception. A new frame is created on
 * top of the existing stack and this method is executed.
 */
void throwException(int offset) {
    Ref method = getRef(core, offset);
    Ref coreType = getRef(core, OBJECT_TYPE);
    executeMethod(coreType, method, 0);
}
// Method ID = 10
void EMLiveMonitor::notifyReadyForPull()
{
  EXEParamList emptyParams;

  executeMethod( 10, emptyParams );
}
示例#24
0
文件: invoke.c 项目: ahua/java
/*
 * Execute the INVOKESTATIC instruction
 */
void op_invokestatic() {
    Ref entry = resolve(u16(1), ID_METHOD);
    if (entry == NULL) { return; } // rollback, gc done
    Ref owner = getRef(entry, ENTRY_OWNER);
    executeMethod(owner, entry, 3);
}
示例#25
0
void detachThread(Thread *thread) {
    Object *group, *excep;
    //ExecEnv *ee = thread->ee;
    //Object *jThread = ee->thread;
    Object *jThread = thread->thread;
    Object *vmthread = (Object*)INST_DATA(jThread)[vmthread_offset];

    /* Get the thread's group */
    group = (Object *)INST_DATA(jThread)[group_offset];

    /* If there's an uncaught exception, call uncaughtException on the thread's
       exception handler, or the thread's group if this is unset */
    if((excep = exceptionOccurred())) {
        FieldBlock *fb = findField(thread_class, SYMBOL(exceptionHandler),
                                                 SYMBOL(sig_java_lang_Thread_UncaughtExceptionHandler));
        Object *thread_handler = fb == NULL ? NULL : (Object *)INST_DATA(jThread)[fb->offset];
        Object *handler = thread_handler == NULL ? group : thread_handler;

        MethodBlock *uncaught_exp = lookupMethod(handler->classobj, SYMBOL(uncaughtException),
                                                 SYMBOL(_java_lang_Thread_java_lang_Throwable__V));

        if(uncaught_exp) {
            clearException();
            DummyFrame dummy;
            executeMethod(&dummy, handler, uncaught_exp, jThread, excep);
        } else
            printException();
    }

    /* remove thread from thread group */
    DummyFrame dummy;
    executeMethod(&dummy, group, (CLASS_CB(group->classobj))->method_table[rmveThrd_mtbl_idx], jThread);

    /* set VMThread ref in Thread object to null - operations after this
       point will result in an IllegalThreadStateException */
    INST_DATA(jThread)[vmthread_offset] = 0;

    /* Remove thread from the ID map hash table */
    deleteThreadFromHash(thread);

    /* Disable suspend to protect lock operation */
    disableSuspend(thread);

    /* Grab global lock, and update thread structures protected by
       it (thread list, thread ID and number of daemon threads) */
    pthread_mutex_lock(&lock);

    /* remove from thread list... */
    if((thread->prev->next = thread->next))
        thread->next->prev = thread->prev;

    /* One less live thread */
    threads_count--;

    /* Recycle the thread's thread ID */
    freeThreadID(thread->id);

    /* Handle daemon thread status */
    if(!INST_DATA(jThread)[daemon_offset])
        non_daemon_thrds--;

    pthread_mutex_unlock(&lock);

    /* notify any threads waiting on VMThread object -
       these are joining this thread */
    objectLock(vmthread);
    objectNotifyAll(vmthread);
    objectUnlock(vmthread);

    /* It is safe to free the thread's ExecEnv and stack now as these are
       only used within the thread.  It is _not_ safe to free the native
       thread structure as another thread may be concurrently accessing it.
       However, they must have a reference to the VMThread -- therefore, it
       is safe to free during GC when the VMThread is determined to be no
       longer reachable. */
//    sysFree(ee->stack);
    //sysFree(ee);

    /* If no more daemon threads notify the main thread (which
       may be waiting to exit VM).  Note, this is not protected
       by lock, but main thread checks again */

    if(non_daemon_thrds == 0) {
        /* No need to bother with disabling suspension
         * around lock, as we're no longer on thread list */
        pthread_mutex_lock(&exit_lock);
        pthread_cond_signal(&exit_cv);
        pthread_mutex_unlock(&exit_lock);
    }

    TRACE("Thread 0x%x id: %d detached from VM\n", thread, thread->id);
}
// Method ID = 9
void EMLiveMonitor::notifyPushingCompleted()
{
  EXEParamList emptyParams;

  executeMethod( 9, emptyParams );
}
示例#27
0
HOT void sendSuperMessage(VMGlobals *g, PyrSymbol *selector, long numArgsPushed)
{
	PyrMethod *meth = NULL;
	PyrMethodRaw *methraw;
	PyrSlot *recvrSlot, *sp;
	PyrClass *classobj;
	long index;
	PyrObject *obj;

	//postfl("->sendMessage\n");
#ifdef GC_SANITYCHECK
	g->gc->SanityCheck();
	CallStackSanity(g, "sendSuperMessage");
#endif
	recvrSlot = g->sp - numArgsPushed + 1;

	classobj = slotRawSymbol(&slotRawClass(&g->method->ownerclass)->superclass)->u.classobj;
	//assert(isKindOfSlot(recvrSlot, classobj));

	lookup_again:
	index = slotRawInt(&classobj->classIndex) + selector->u.index;
	meth = gRowTable[index];

	if (slotRawSymbol(&meth->name) != selector) {
		doesNotUnderstand(g, selector, numArgsPushed);
	} else {
		methraw = METHRAW(meth);
		//postfl("methraw->methType %d\n", methraw->methType);
		switch (methraw->methType) {
			case methNormal : /* normal msg send */
				executeMethod(g, meth, numArgsPushed);
				break;
			case methReturnSelf : /* return self */
				g->sp -= numArgsPushed - 1;
				break;
			case methReturnLiteral : /* return literal */
				sp = g->sp -= numArgsPushed - 1;
				slotCopy(sp, &meth->selectors); /* in this case selectors is just a single value */
				break;
			case methReturnArg : /* return an argument */
				sp = g->sp -= numArgsPushed - 1;
				index = methraw->specialIndex; // zero is index of the first argument
				if (index < numArgsPushed) {
					slotCopy(sp, sp + index);
				} else {
					slotCopy(sp, &slotRawObject(&meth->prototypeFrame)->slots[index]);
				}
				break;
			case methReturnInstVar : /* return inst var */
				sp = g->sp -= numArgsPushed - 1;
				index = methraw->specialIndex;
				slotCopy(sp, &slotRawObject(recvrSlot)->slots[index]);
				break;
			case methAssignInstVar : /* assign inst var */
				sp = g->sp -= numArgsPushed - 1;
				index = methraw->specialIndex;
				obj = slotRawObject(recvrSlot);
				if (obj->IsImmutable()) { StoreToImmutableB(g, sp, g->ip); }
				else {
					if (numArgsPushed >= 2) {
						slotCopy(&obj->slots[index], sp + 1);
						g->gc->GCWrite(obj, sp + 1);
					} else {
						SetNil(&obj->slots[index]);
					}
					slotCopy(sp, recvrSlot);
				}
				break;
			case methReturnClassVar : /* return class var */
				sp = g->sp -= numArgsPushed - 1;
				slotCopy(sp, &g->classvars->slots[methraw->specialIndex]);
				break;
			case methAssignClassVar : /* assign class var */
				sp = g->sp -= numArgsPushed - 1;
				if (numArgsPushed >= 2) {
					slotCopy(&g->classvars->slots[methraw->specialIndex], sp + 1);
					g->gc->GCWrite(g->classvars, sp + 1);
				} else {
					SetNil(&g->classvars->slots[methraw->specialIndex]);
				}
				slotCopy(sp, recvrSlot);
				break;
			case methRedirect : /* send a different selector to self, e.g. this.subclassResponsibility */
				if (numArgsPushed < methraw->numargs) { // not enough args pushed
					/* push default arg values */
					PyrSlot *pslot, *qslot;
					long m, mmax;
					pslot = g->sp;
					qslot = slotRawObject(&meth->prototypeFrame)->slots + numArgsPushed - 1;
					for (m=0, mmax=methraw->numargs - numArgsPushed; m<mmax; ++m) slotCopy(++pslot, ++qslot);
					numArgsPushed = methraw->numargs;
					g->sp += mmax;
				}
				selector = slotRawSymbol(&meth->selectors);
				goto lookup_again;
			case methRedirectSuper : /* send a different selector to self, e.g. this.subclassResponsibility */
				if (numArgsPushed < methraw->numargs) { // not enough args pushed
					/* push default arg values */
					PyrSlot *pslot, *qslot;
					long m, mmax;
					pslot = g->sp;
					qslot = slotRawObject(&meth->prototypeFrame)->slots + numArgsPushed - 1;
					for (m=0, mmax=methraw->numargs - numArgsPushed; m<mmax; ++m) slotCopy(++pslot, ++qslot);
					numArgsPushed = methraw->numargs;
					g->sp += mmax;
				}
				selector = slotRawSymbol(&meth->selectors);
				classobj = slotRawSymbol(&slotRawClass(&meth->ownerclass)->superclass)->u.classobj;
				goto lookup_again;
			case methForwardInstVar : /* forward to an instance variable */
				if (numArgsPushed < methraw->numargs) { // not enough args pushed
					/* push default arg values */
					PyrSlot *pslot, *qslot;
					long m, mmax;
					pslot = g->sp;
					qslot = slotRawObject(&meth->prototypeFrame)->slots + numArgsPushed - 1;
					for (m=0, mmax=methraw->numargs - numArgsPushed; m<mmax; ++m) slotCopy(++pslot, ++qslot);
					numArgsPushed = methraw->numargs;
					g->sp += mmax;
				}
				selector = slotRawSymbol(&meth->selectors);
				index = methraw->specialIndex;
				slotCopy(recvrSlot, &slotRawObject(recvrSlot)->slots[index]);

				classobj = classOfSlot(recvrSlot);

				goto lookup_again;
			case methForwardClassVar : /* forward to a class variable */
				if (numArgsPushed < methraw->numargs) { // not enough args pushed
					/* push default arg values */
					PyrSlot *pslot, *qslot;
					long m, mmax;
					pslot = g->sp;
					qslot = slotRawObject(&meth->prototypeFrame)->slots + numArgsPushed - 1;
					for (m=0, mmax=methraw->numargs - numArgsPushed; m<mmax; ++m) slotCopy(++pslot, ++qslot);
					numArgsPushed = methraw->numargs;
					g->sp += mmax;
				}
				selector = slotRawSymbol(&meth->selectors);
				slotCopy(recvrSlot, &g->classvars->slots[methraw->specialIndex]);

				classobj = classOfSlot(recvrSlot);

				goto lookup_again;
			case methPrimitive : /* primitive */
				doPrimitive(g, meth, (int)numArgsPushed);
#ifdef GC_SANITYCHECK
	g->gc->SanityCheck();
#endif
				break;
			/*
			case methMultDispatchByClass : {
				index = methraw->specialIndex;
				if (index < numArgsPushed) {
					classobj = slotRawObject(sp + index)->classptr;
					selector = slotRawSymbol(&meth->selectors);
					goto lookup_again;
				} else {
					doesNotUnderstand(g, selector, numArgsPushed);
				}
			} break;
			case methMultDispatchByValue : {
				index = methraw->specialIndex;
				if (index < numArgsPushed) {
					index = arrayAtIdentityHashInPairs(array, b);
					meth = slotRawObject(&meth->selectors)->slots[index + 1].uom;
					goto meth_select_again;
				} else {
					doesNotUnderstand(g, selector, numArgsPushed);
				}
			} break;
			*/

		}
	}
#if TAILCALLOPTIMIZE
	g->tailCall = 0;
#endif
#ifdef GC_SANITYCHECK
	g->gc->SanityCheck();
	CallStackSanity(g, "<sendSuperMessage");
#endif
	//postfl("<-sendMessage\n");
}
示例#28
0
void initialiseThreadStage2(InitArgs *args) {
    Object *java_thread;
    Class *thrdGrp_class;
    MethodBlock *run, *remove_thread;
    FieldBlock *group, *priority, *root, *threadId;
    FieldBlock *vmThread = NULL, *thread = NULL;
    FieldBlock *vmData, *daemon, *name;

    /* Load thread class and register reference for compaction threading */
    thread_class = findSystemClass0(SYMBOL(java_lang_Thread));
    registerStaticClassRef(&thread_class);

    if(thread_class != NULL) {
        vmThread = findField(thread_class, SYMBOL(vmThread), SYMBOL(sig_java_lang_VMThread));
        daemon = findField(thread_class, SYMBOL(daemon), SYMBOL(Z));
        name = findField(thread_class, SYMBOL(name), SYMBOL(sig_java_lang_String));
        group = findField(thread_class, SYMBOL(group), SYMBOL(sig_java_lang_ThreadGroup));
        priority = findField(thread_class, SYMBOL(priority), SYMBOL(I));
        threadId = findField(thread_class, SYMBOL(threadId), SYMBOL(J));

        init_mb = findMethod(thread_class, SYMBOL(object_init),
                             SYMBOL(_java_lang_VMThread_java_lang_String_I_Z__V));
        run = findMethod(thread_class, SYMBOL(run), SYMBOL(___V));

        vmthread_class = findSystemClass0(SYMBOL(java_lang_VMThread));
        CLASS_CB(vmthread_class)->flags |= VMTHREAD;

        /* Register class reference for compaction threading */
        registerStaticClassRef(&vmthread_class);

        if(vmthread_class != NULL) {
            thread = findField(vmthread_class, SYMBOL(thread), SYMBOL(sig_java_lang_Thread));
            vmData = findField(vmthread_class, SYMBOL(vmData), SYMBOL(I));
        }
    }

    /* findField and findMethod do not throw an exception... */
    if((init_mb == NULL) || (vmData == NULL) || (run == NULL) || (daemon == NULL) ||
       (name == NULL) || (group == NULL) || (priority == NULL) || (vmThread == NULL) ||
       (thread == NULL) || (threadId == NULL))
        goto error;

    vmthread_offset = vmThread->offset;
    thread_offset = thread->offset;
    vmData_offset = vmData->offset;
    daemon_offset = daemon->offset;
    group_offset = group->offset;
    priority_offset = priority->offset;
    threadId_offset = threadId->offset;
    name_offset = name->offset;
    run_mtbl_idx = run->method_table_index;

    /* Initialise the Java-level thread objects for the main thread */
    java_thread = initJavaThread(&main_thread, FALSE, "main");

    /* Main thread is now sufficiently setup to be able to run the thread group
       initialiser.  This is essential to create the root thread group */
    thrdGrp_class = findSystemClass(SYMBOL(java_lang_ThreadGroup));

    root = findField(thrdGrp_class, SYMBOL(root), SYMBOL(sig_java_lang_ThreadGroup));

    addThread_mb = findMethod(thrdGrp_class, SYMBOL(addThread),
                                             SYMBOL(_java_lang_Thread_args__void));

    remove_thread = findMethod(thrdGrp_class, SYMBOL(removeThread),
                                              SYMBOL(_java_lang_Thread_args__void));

    /* findField and findMethod do not throw an exception... */
    if((root == NULL) || (addThread_mb == NULL) || (remove_thread == NULL))
        goto error;

    rmveThrd_mtbl_idx = remove_thread->method_table_index;

    /* Add the main thread to the root thread group */
    INST_DATA(java_thread)[group_offset] = root->static_value;
    {
        DummyFrame dummy;
        executeMethod(&dummy, ((Object*)root->static_value), addThread_mb, java_thread);
    }

    // dyn
    INST_DATA(java_thread)[vmthread_offset] = 0;

    /* Setup signal handling.  This will be inherited by all
       threads created within Java */
    initialiseSignals();

    /* Create the signal handler thread.  It is responsible for
       catching and handling SIGQUIT (thread dump) and SIGINT
       (user-termination of the VM, e.g. via Ctrl-C).  Note it
       must be a valid Java-level thread as it needs to run the
       shutdown hooks in the event of user-termination */
    createVMThread("Signal Handler", dumpThreadsLoop);

    return;

error:
    jam_fprintf(stderr, "Error initialising VM (initialiseMainThread)\nCheck "
                        "the README for compatible versions of GNU Classpath\n");
    printException();
    exitVM(1);
}
示例#29
0
void doesNotUnderstand(VMGlobals *g, PyrSymbol *selector,
	long numArgsPushed)
{
	PyrSlot *qslot, *pslot, *pend;
	long i, index;
	PyrSlot *uniqueMethodSlot, *arraySlot, *recvrSlot, *selSlot, *slot;
	PyrClass *classobj;
	PyrMethod *meth;
	PyrObject *array;

#ifdef GC_SANITYCHECK
	g->gc->SanityCheck();
#endif
	// move args up by one to make room for selector
	qslot = g->sp + 1;
	pslot = g->sp + 2;
	pend = pslot - numArgsPushed + 1;
	while (pslot > pend) *--pslot = *--qslot;

	selSlot = g->sp - numArgsPushed + 2;
	SetSymbol(selSlot, selector);
	g->sp++;

	recvrSlot = selSlot - 1;

	classobj = classOfSlot(recvrSlot);

	index = slotRawInt(&classobj->classIndex) + s_nocomprendo->u.index;
	meth = gRowTable[index];


	if (slotRawClass(&meth->ownerclass) == class_object) {
		// lookup instance specific method
		uniqueMethodSlot = &g->classvars->slots[cvxUniqueMethods];
		if (isKindOfSlot(uniqueMethodSlot, class_identdict)) {
			arraySlot = slotRawObject(uniqueMethodSlot)->slots + ivxIdentDict_array;
			if ((IsObj(arraySlot) && (array = slotRawObject(arraySlot))->classptr == class_array)) {
				i = arrayAtIdentityHashInPairs(array, recvrSlot);
				if (i >= 0) {
					slot = array->slots + i;
					if (NotNil(slot)) {
						++slot;
						if (isKindOfSlot(slot, class_identdict)) {
							arraySlot = slotRawObject(slot)->slots + ivxIdentDict_array;
							if ((IsObj(arraySlot) && (array = slotRawObject(arraySlot))->classptr == class_array)) {
								i = arrayAtIdentityHashInPairs(array, selSlot);
								if (i >= 0) {
									slot = array->slots + i;
									if (NotNil(slot)) {
										++slot;
										slotCopy(selSlot, recvrSlot);
										slotCopy(recvrSlot, slot);
										blockValue(g, (int)numArgsPushed+1);
										return;
									}
								}
							}
						}
					}
				}
			}
		}
	}

	executeMethod(g, meth, numArgsPushed+1);

#ifdef GC_SANITYCHECK
	g->gc->SanityCheck();
#endif
}