void createJavaThread(Object *jThread, long long stack_size) { //ExecEnv *ee; Thread *thread; Thread *self = threadSelf(); Object *vmthread = allocObject(vmthread_class); if(vmthread == NULL) return; disableSuspend(self); pthread_mutex_lock(&lock); if(INST_DATA(jThread)[vmthread_offset]) { pthread_mutex_unlock(&lock); enableSuspend(self); signalException(java_lang_IllegalThreadStateException, "thread already started"); return; } //ee = (ExecEnv*)sysMalloc(sizeof(ExecEnv)); thread = new Thread; //memset(ee, 0, sizeof(ExecEnv)); // thread->ee = ee; // ee->thread = jThread; thread->thread = jThread; // ee->stack_size = stack_size; INST_DATA(vmthread)[vmData_offset] = (uintptr_t)thread; INST_DATA(vmthread)[thread_offset] = (uintptr_t)jThread; INST_DATA(jThread)[vmthread_offset] = (uintptr_t)vmthread; pthread_mutex_unlock(&lock); if(pthread_create(&thread->tid, &attributes, threadStart, thread)) { INST_DATA(jThread)[vmthread_offset] = 0; //sysFree(ee); enableSuspend(self); signalException(java_lang_OutOfMemoryError, "can't create thread"); return; } pthread_mutex_lock(&lock); /* Wait for thread to start */ while(thread->state == 0) pthread_cond_wait(&cv, &lock); pthread_mutex_unlock(&lock); enableSuspend(self); }
int main(int argc, char *argv[]) { Class *array_class, *main_class; Object *system_loader, *array; MethodBlock *mb; InitArgs args; int class_arg; char *cpntr; int status; int i; setDefaultInitArgs(&args); class_arg = parseCommandLine(argc, argv, &args); args.main_stack_base = &array_class; if(!initVM(&args)) { printf("Could not initialise VM. Aborting.\n"); exit(1); } if((system_loader = getSystemClassLoader()) == NULL) goto error; mainThreadSetContextClassLoader(system_loader); for(cpntr = argv[class_arg]; *cpntr; cpntr++) if(*cpntr == '.') *cpntr = '/'; main_class = findClassFromClassLoader(argv[class_arg], system_loader); if(main_class != NULL) initClass(main_class); if(exceptionOccurred()) goto error; mb = lookupMethod(main_class, SYMBOL(main), SYMBOL(_array_java_lang_String__V)); if(mb == NULL || !(mb->access_flags & ACC_STATIC)) { signalException(java_lang_NoSuchMethodError, "main"); goto error; } /* Create the String array holding the command line args */ i = class_arg + 1; if((array_class = findArrayClass(SYMBOL(array_java_lang_String))) && (array = allocArray(array_class, argc - i, sizeof(Object*)))) { Object **args = ARRAY_DATA(array, Object*) - i; for(; i < argc; i++) if(!(args[i] = Cstr2String(argv[i]))) break; /* Call the main method */ if(i == argc) executeStaticMethod(main_class, mb, array); }
static int initAnnotation() { Class *enum_cls, *map_cls, *anno_inv_cls, *obj_ary_cls; Class *anno_ary_cls, *dbl_anno_ary_cls; enum_cls = findSystemClass("java/lang/Enum"); map_cls = findSystemClass("java/util/HashMap"); anno_inv_cls = findSystemClass("sun/reflect/annotation/Annotation" "InvocationHandler"); obj_ary_cls = findArrayClass("[Ljava/lang/Object;"); anno_ary_cls = findArrayClass("[Ljava/lang/annotation/Annotation;"); dbl_anno_ary_cls = findArrayClass("[[Ljava/lang/annotation/Annotation;"); if(!enum_cls || !map_cls || !anno_inv_cls || !obj_ary_cls || !anno_ary_cls || !dbl_anno_ary_cls) return FALSE; map_init_mb = findMethod(map_cls, SYMBOL(object_init), SYMBOL(___V)); map_put_mb = findMethod(map_cls, SYMBOL(put), newUtf8("(Ljava/lang/Object;Ljava/lang/Object;)" "Ljava/lang/Object;")); anno_create_mb = findMethod(anno_inv_cls, newUtf8("create"), newUtf8("(Ljava/lang/Class;Ljava/util/Map;)" "Ljava/lang/annotation/Annotation;")); enum_valueof_mb = findMethod(enum_cls, newUtf8("valueOf"), newUtf8("(Ljava/lang/Class;Ljava/lang/String;)" "Ljava/lang/Enum;")); if(!map_init_mb || !map_put_mb || !anno_create_mb || !enum_valueof_mb) { /* FindMethod doesn't throw an exception... */ signalException(java_lang_InternalError, "Expected field/method doesn't exist"); return FALSE; } registerStaticClassRefLocked(&enum_class, enum_cls); registerStaticClassRefLocked(&map_class, map_cls); registerStaticClassRefLocked(&anno_inv_class, anno_inv_cls); registerStaticClassRefLocked(&obj_array_class, obj_ary_cls); registerStaticClassRefLocked(&anno_array_class, anno_ary_cls); registerStaticClassRefLocked(&dbl_anno_array_class, dbl_anno_ary_cls); return anno_inited = TRUE; }
int monitorWait0(Monitor *mon, Thread *self, long long ms, int ns, int blocked, int interruptible) { char timed = (ms != 0) || (ns != 0); char interrupted = FALSE; char timeout = FALSE; struct timespec ts; int old_count; /* Check we own the monitor */ if(mon->owner != self) return FALSE; disableSuspend(self); /* Unlock the monitor. As it could be recursively locked remember the recursion count */ old_count = mon->count; mon->owner = NULL; mon->count = 0; /* Counter used in thin-lock deflation */ mon->in_wait++; self->wait_mon = mon; if(timed) { getTimeoutRelative(&ts, ms, ns); self->state = TIMED_WAITING; } else self->state = blocked ? BLOCKED : WAITING; if(interruptible && self->interrupted) interrupted = TRUE; else { if(blocked) { self->blocked_mon = mon; self->blocked_count++; } else self->waited_count++; self->interrupting = FALSE; /* Add the thread onto the end of the wait set */ waitSetAppend(mon, self); while(self->wait_next != NULL && !self->interrupting && !timeout) if(timed) { timeout = pthread_cond_timedwait(&self->wait_cv, &mon->lock, &ts) == ETIMEDOUT; /* On Linux/i386 systems using LinuxThreads, pthread_cond_timedwait is implemented using sigjmp/longjmp. This resets the fpu control word back to 64-bit precision. The macro is empty for sane platforms. */ FPU_HACK; } else pthread_cond_wait(&self->wait_cv, &mon->lock); } /* If we've been interrupted or timed-out, we will not have been removed from the wait set. If we have, we must have been notified afterwards. In this case, the notify has been lost, and we must signal another thread */ if(self->interrupting || timeout) { /* An interrupt after a timeout remains pending */ interrupted = interruptible && !timeout; if(self->wait_next != NULL) waitSetUnlinkThread(mon, self); else { /* Notify lost. Signal another thread only if it was on the wait set at the time of the notify */ if(mon->wait_set != NULL && mon->wait_set->wait_id < self->notify_id) { Thread *thread = waitSetSignalNext(mon); thread->notify_id = self->notify_id; } } } self->state = RUNNING; self->wait_mon = NULL; if(blocked) self->blocked_mon = NULL; /* Restore the monitor owner and recursion count */ mon->count = old_count; mon->owner = self; mon->in_wait--; enableSuspend(self); if(interrupted) { self->interrupted = FALSE; signalException(java_lang_InterruptedException, NULL); } return TRUE; }
int classlibInitReflection() { Class *cons_ref_cls, *mthd_ref_cls, *fld_ref_cls; FieldBlock *cons_slot_fb, *cons_class_fb, *cons_param_fb; FieldBlock *mthd_slot_fb, *mthd_class_fb, *mthd_ret_fb, *mthd_param_fb; FieldBlock *fld_slot_fb, *fld_class_fb; cons_ref_cls = findSystemClass(SYMBOL(java_lang_reflect_Constructor)); mthd_ref_cls = findSystemClass(SYMBOL(java_lang_reflect_Method)); fld_ref_cls = findSystemClass(SYMBOL(java_lang_reflect_Field)); if(!cons_ref_cls || !mthd_ref_cls || !fld_ref_cls) return FALSE; cons_slot_fb = findField(cons_ref_cls, SYMBOL(slot), SYMBOL(I)); cons_class_fb = findField(cons_ref_cls, SYMBOL(clazz), SYMBOL(sig_java_lang_Class)); cons_param_fb = findField(cons_ref_cls, SYMBOL(parameterTypes), SYMBOL(array_java_lang_Class)); mthd_slot_fb = findField(mthd_ref_cls, SYMBOL(slot), SYMBOL(I)); mthd_class_fb = findField(mthd_ref_cls, SYMBOL(clazz), SYMBOL(sig_java_lang_Class)); mthd_ret_fb = findField(mthd_ref_cls, SYMBOL(returnType), SYMBOL(sig_java_lang_Class)); mthd_param_fb = findField(mthd_ref_cls, SYMBOL(parameterTypes), SYMBOL(array_java_lang_Class)); fld_slot_fb = findField(fld_ref_cls, SYMBOL(slot), SYMBOL(I)); fld_class_fb = findField(fld_ref_cls, SYMBOL(clazz), SYMBOL(sig_java_lang_Class)); fld_init_mb = findMethod(fld_ref_cls, SYMBOL(object_init), SYMBOL(java_lang_reflect_field_init_sig)); cons_init_mb = findMethod(cons_ref_cls, SYMBOL(object_init), SYMBOL(java_lang_reflect_cons_init_sig)); mthd_init_mb = findMethod(mthd_ref_cls, SYMBOL(object_init), SYMBOL(java_lang_reflect_mthd_init_sig)); mthd_invoke_mb = findMethod(mthd_ref_cls, SYMBOL(invoke), SYMBOL(java_lang_reflect_mthd_invoke_sig)); if(!fld_init_mb || !cons_init_mb || !mthd_init_mb || !cons_slot_fb || !cons_class_fb || !cons_param_fb || !mthd_slot_fb || !mthd_class_fb || !mthd_ret_fb || !mthd_param_fb || !fld_slot_fb || !fld_class_fb || !mthd_invoke_mb) { /* Find Field/Method doesn't throw an exception... */ signalException(java_lang_InternalError, "Expected reflection method/field doesn't exist"); return FALSE; } cons_slot_offset = cons_slot_fb->u.offset; cons_class_offset = cons_class_fb->u.offset; cons_param_offset = cons_param_fb->u.offset; mthd_slot_offset = mthd_slot_fb->u.offset; mthd_class_offset = mthd_class_fb->u.offset; mthd_ret_offset = mthd_ret_fb->u.offset; mthd_param_offset = mthd_param_fb->u.offset; fld_slot_offset = fld_slot_fb->u.offset; fld_class_offset = fld_class_fb->u.offset; registerStaticClassRefLocked(&cons_reflect_class, cons_ref_cls); registerStaticClassRefLocked(&method_reflect_class, mthd_ref_cls); registerStaticClassRefLocked(&field_reflect_class, fld_ref_cls); return TRUE; }
int monitorWait0(Monitor *mon, Thread *self, long long ms, int ns, int blocked, int interruptible) { char timed = (ms != 0) || (ns != 0); char interrupted = FALSE; char timeout = FALSE; int ts = 0; int old_count = 0; // Check we own the monitor if (mon->owner != self) return FALSE; disableSuspend(self); // Unlock the monitor. As it could be recursively // locked remember the recursion count old_count = mon->count; mon->owner = NULL; mon->count = 0; // Counter used in thin-lock deflation mon->in_wait++; self->wait_mon = mon; if (timed) { ts = getTimeoutRelative(ms, ns); self->state = TIMED_WAITING; } else { self->state = blocked ? BLOCKED : WAITING; } if (interruptible && self->interrupted) { interrupted = TRUE; } else { if (blocked) { self->blocked_mon = mon; self->blocked_count++; } else { self->waited_count++; } self->interrupting = FALSE; // Add the thread onto the end of the wait set waitSetAppend(mon, self); while (self->wait_next != NULL && !self->interrupting && !timeout) if (timed) { timeout = xi_thread_cond_timedwait(&self->wait_cv, &mon->lock, ts) == XI_COND_RV_ERR_TIMEOUT; // On Linux/i386 systems using LinuxThreads, // pthread_cond_timedwait is implemented using // sigjmp/longjmp. This resets the fpu control // word back to 64-bit precision. The macro is // empty for sane platforms. FPU_HACK; } else { xi_thread_cond_wait(&self->wait_cv, &mon->lock); } } // If we've been interrupted or timed-out, we will not have been // removed from the wait set. If we have, we must have been // notified afterwards. In this case, the notify has been lost, // and we must signal another thread if (self->interrupting || timeout) { // An interrupt after a timeout remains pending interrupted = interruptible && !timeout; if (self->wait_next != NULL) { waitSetUnlinkThread(mon, self); } else { // Notify lost. Signal another thread only if it // was on the wait set at the time of the notify if (mon->wait_set != NULL && mon->wait_set->wait_id < self->notify_id) { Thread *thread = waitSetSignalNext(mon); thread->notify_id = self->notify_id; } } } self->state = RUNNING; self->wait_mon = NULL; if (blocked) { self->blocked_mon = NULL; } // Restore the monitor owner and recursion count mon->count = old_count; mon->owner = self; mon->in_wait--; enableSuspend(self); if (interrupted) { self->interrupted = FALSE; signalException(java_lang_InterruptedException, NULL); } return TRUE; }
static int initReflection() { Class *cls_ary_cls, *cons_ary_cls, *cons_ref_cls, *mthd_ary_cls; Class *mthd_ref_cls, *fld_ary_cls, *fld_ref_cls, *vm_cons_cls; Class *vm_mthd_cls, *vm_fld_cls; FieldBlock *vm_cons_slot_fb, *vm_cons_class_fb, *vm_cons_param_fb; FieldBlock *vm_cons_cons_fb, *vm_mthd_slot_fb, *vm_mthd_class_fb; FieldBlock *vm_mthd_ret_fb, *vm_mthd_param_fb, *vm_mthd_m_fb; FieldBlock *vm_fld_slot_fb, *vm_fld_class_fb, *vm_fld_type_fb; FieldBlock *vm_fld_f_fb, *cons_cons_fb, *mthd_m_fb, *fld_f_fb; FieldBlock *acc_flag_fb; cls_ary_cls = findArrayClass(SYMBOL(array_java_lang_Class)); cons_ary_cls = findArrayClass(SYMBOL(array_java_lang_reflect_Constructor)); cons_ref_cls = findSystemClass(SYMBOL(java_lang_reflect_Constructor)); vm_cons_cls = findSystemClass(SYMBOL(java_lang_reflect_VMConstructor)); mthd_ary_cls = findArrayClass(SYMBOL(array_java_lang_reflect_Method)); mthd_ref_cls = findSystemClass(SYMBOL(java_lang_reflect_Method)); vm_mthd_cls = findSystemClass(SYMBOL(java_lang_reflect_VMMethod)); fld_ary_cls = findArrayClass(SYMBOL(array_java_lang_reflect_Field)); fld_ref_cls = findSystemClass(SYMBOL(java_lang_reflect_Field)); vm_fld_cls = findSystemClass(SYMBOL(java_lang_reflect_VMField)); if(!cls_ary_cls || !cons_ary_cls || !cons_ref_cls || !mthd_ary_cls || !mthd_ref_cls || !fld_ary_cls || !fld_ref_cls || !vm_cons_cls || !vm_mthd_cls || !vm_fld_cls) return FALSE; vm_cons_slot_fb = findField(vm_cons_cls, SYMBOL(slot), SYMBOL(I)); vm_cons_class_fb = findField(vm_cons_cls, SYMBOL(clazz), SYMBOL(sig_java_lang_Class)); vm_cons_param_fb = findField(vm_cons_cls, SYMBOL(parameterTypes), SYMBOL(array_java_lang_Class)); vm_cons_cons_fb = findField(vm_cons_cls, SYMBOL(cons), SYMBOL(sig_java_lang_reflect_Constructor)); vm_mthd_slot_fb = findField(vm_mthd_cls, SYMBOL(slot), SYMBOL(I)); vm_mthd_class_fb = findField(vm_mthd_cls, SYMBOL(clazz), SYMBOL(sig_java_lang_Class)); vm_mthd_ret_fb = findField(vm_mthd_cls, SYMBOL(returnType), SYMBOL(sig_java_lang_Class)); vm_mthd_param_fb = findField(vm_mthd_cls, SYMBOL(parameterTypes), SYMBOL(array_java_lang_Class)); vm_mthd_m_fb = findField(vm_mthd_cls, SYMBOL(m), SYMBOL(sig_java_lang_reflect_Method)); vm_fld_slot_fb = findField(vm_fld_cls, SYMBOL(slot), SYMBOL(I)); vm_fld_class_fb = findField(vm_fld_cls, SYMBOL(clazz), SYMBOL(sig_java_lang_Class)); vm_fld_type_fb = findField(vm_fld_cls, SYMBOL(type), SYMBOL(sig_java_lang_Class)); vm_fld_f_fb = findField(vm_fld_cls, SYMBOL(f), SYMBOL(sig_java_lang_reflect_Field)); cons_cons_fb = findField(cons_ref_cls, SYMBOL(cons), SYMBOL(sig_java_lang_reflect_VMConstructor)); mthd_m_fb = findField(mthd_ref_cls, SYMBOL(m), SYMBOL(sig_java_lang_reflect_VMMethod)); fld_f_fb = findField(fld_ref_cls, SYMBOL(f), SYMBOL(sig_java_lang_reflect_VMField)); acc_flag_fb = lookupField(cons_ref_cls, SYMBOL(flag), SYMBOL(Z)); if(!vm_cons_slot_fb || !vm_cons_class_fb || !vm_cons_param_fb || !vm_cons_cons_fb || !vm_mthd_slot_fb || !vm_mthd_class_fb || !vm_mthd_ret_fb || !vm_mthd_m_fb || !vm_mthd_param_fb || !vm_fld_slot_fb || !vm_fld_class_fb || !vm_fld_type_fb || !vm_fld_f_fb || !cons_cons_fb || !mthd_m_fb || !fld_f_fb || !acc_flag_fb) { /* Find Field/Method doesn't throw an exception... */ signalException(java_lang_InternalError, "Expected reflection field doesn't exist"); return FALSE; } vm_cons_slot_offset = vm_cons_slot_fb->u.offset; vm_cons_class_offset = vm_cons_class_fb->u.offset; vm_cons_param_offset = vm_cons_param_fb->u.offset; vm_cons_cons_offset = vm_cons_cons_fb->u.offset; vm_mthd_slot_offset = vm_mthd_slot_fb->u.offset; vm_mthd_class_offset = vm_mthd_class_fb->u.offset; vm_mthd_ret_offset = vm_mthd_ret_fb->u.offset; vm_mthd_param_offset = vm_mthd_param_fb->u.offset; vm_mthd_m_offset = vm_mthd_m_fb->u.offset; vm_fld_slot_offset = vm_fld_slot_fb->u.offset; vm_fld_class_offset = vm_fld_class_fb->u.offset; vm_fld_type_offset = vm_fld_type_fb->u.offset; vm_fld_f_offset = vm_fld_f_fb->u.offset; cons_cons_offset = cons_cons_fb->u.offset; mthd_m_offset = mthd_m_fb->u.offset; fld_f_offset = fld_f_fb->u.offset; acc_flag_offset = acc_flag_fb->u.offset; registerStaticClassRefLocked(&class_array_class, cls_ary_cls); registerStaticClassRefLocked(&cons_array_class, cons_ary_cls); registerStaticClassRefLocked(&method_array_class, mthd_ary_cls); registerStaticClassRefLocked(&field_array_class, fld_ary_cls); registerStaticClassRefLocked(&cons_reflect_class, cons_ref_cls); registerStaticClassRefLocked(&vmcons_reflect_class, vm_cons_cls); registerStaticClassRefLocked(&method_reflect_class, mthd_ref_cls); registerStaticClassRefLocked(&vmmethod_reflect_class, vm_mthd_cls); registerStaticClassRefLocked(&field_reflect_class, fld_ref_cls); registerStaticClassRefLocked(&vmfield_reflect_class, vm_fld_cls); return inited = TRUE; }