Skip to content

Commit

Permalink
fix thread interrupted, fix threadgroup, fix zip path with utf-8
Browse files Browse the repository at this point in the history
  • Loading branch information
digitalgust committed Dec 23, 2024
1 parent 3d0b0f5 commit 7c185af
Show file tree
Hide file tree
Showing 13 changed files with 178 additions and 98 deletions.
2 changes: 2 additions & 0 deletions minijvm/c/jvm/global.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ c8 *STRS_CLASS_EXCEPTION[] = {
"java.lang.ClassCastException",
"java.lang.ArrayIndexOutOfBoundsException",
"java.lang.InstantiationException",
"java.lang.InterruptedException",
};

c8 const *STR_CLASS_JAVA_LANG_BOOLEAN = "java/lang/Boolean";
Expand All @@ -58,6 +59,7 @@ c8 const *STR_CLASS_JAVA_LANG_STRING = "java/lang/String";
c8 const *STR_CLASS_JAVA_LANG_STRINGBUILDER = "java/lang/StringBuilder";
c8 const *STR_CLASS_JAVA_LANG_OBJECT = "java/lang/Object";
c8 const *STR_CLASS_JAVA_LANG_THREAD = "java/lang/Thread";
c8 const *STR_CLASS_JAVA_LANG_INTERRUPTEDEXCEPTION = "java/lang/InterruptedException";
c8 const *STR_CLASS_JAVA_LANG_CLASS = "java/lang/Class";
c8 const *STR_CLASS_JAVA_LANG_CLASSLOADER = "java/lang/ClassLoader";
c8 const *STR_CLASS_JAVA_LANG_REF_REFERENCE = "java/lang/ref/Reference";
Expand Down
9 changes: 5 additions & 4 deletions minijvm/c/jvm/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,6 @@ static s32 filterClassName(Utf8String *clsName) {
if (offset < 0 && thrd_info->suspend_count) {\
runtime->pc = ip;\
runtime->stack->sp = sp;\
if (thrd_info->is_interrupt) {\
goto label_exit_while;\
}\
check_suspend_and_pause(runtime);\
}\
}
Expand Down Expand Up @@ -601,6 +598,10 @@ s32 execute_method_impl(MethodInfo *method, Runtime *pruntime) {

if (method->is_sync)_synchronized_lock_method(method, runtime);

if (runtime->thrd_info->is_stop) {//if stop=1 then exit thread
goto label_exit_while;
}

if (JIT_ENABLE && ca->jit.state == JIT_GEN_SUCCESS) {
//jvm_printf("jit call %s.%s()\n", method->_this_class->name->data, method->name->data);
ret = ca->jit.func(method, runtime);
Expand Down Expand Up @@ -3011,7 +3012,7 @@ s32 execute_method_impl(MethodInfo *method, Runtime *pruntime) {
if (fi->isrefer) {// garbage collection flag
*ip = op_putfield_ref;
} else {
// non-reference type
// non-reference type
switch (fi->datatype_bytes) {
case 4: {
*ip = op_putfield_int;
Expand Down
2 changes: 1 addition & 1 deletion minijvm/c/jvm/jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1158,7 +1158,7 @@ void gen_jit_suspend_check_func() {
{
sljit_emit_op1(C, SLJIT_MOV_P, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_sw) * LOCAL_R2, SLJIT_R2, 0);
_gen_save_sp_ip(C);
sljit_emit_op1(C, SLJIT_MOV_U8, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(JavaThreadInfo, is_interrupt));
sljit_emit_op1(C, SLJIT_MOV_U8, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(JavaThreadInfo, is_stop));
jump_to_interrupted = sljit_emit_cmp(C, SLJIT_NOT_EQUAL, SLJIT_R1, 0, SLJIT_IMM, 0);
{
jump_not_interrupted = sljit_emit_jump(C, SLJIT_JUMP);
Expand Down
73 changes: 8 additions & 65 deletions minijvm/c/jvm/jni_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1465,19 +1465,9 @@ s32 org_mini_zip_ZipFile_getEntryIndex0(Runtime *runtime, JClass *clazz) {
Instance *name_arr = localvar_getRefer(runtime->localvar, 1);
s32 ret = -1;
if (zip_path_arr && name_arr) {
Utf8String *filepath = utf8_create_c(zip_path_arr->arr_body);
ByteBuf *zip_path = bytebuf_create(0);
conv_utf8_2_platform_encoding(zip_path, filepath);
utf8_clear(filepath);
utf8_append_c(filepath, name_arr->arr_body);
ByteBuf *name = bytebuf_create(0);
//conv_utf8_2_platform_encoding(name, filepath);

ret = zip_get_file_index(zip_path->buf, utf8_cstr(filepath));
ret = zip_get_file_index(zip_path_arr->arr_body, name_arr->arr_body);

bytebuf_destory(zip_path);
bytebuf_destory(name);
utf8_destory(filepath);
}
push_int(runtime->stack, ret);
#if _JVM_DEBUG_LOG_LEVEL > 5
Expand All @@ -1492,19 +1482,9 @@ s32 org_mini_zip_ZipFile_getEntrySize0(Runtime *runtime, JClass *clazz) {
Instance *name_arr = localvar_getRefer(runtime->localvar, 1);
s64 ret = -1;
if (zip_path_arr && name_arr) {
Utf8String *filepath = utf8_create_c(zip_path_arr->arr_body);
ByteBuf *zip_path = bytebuf_create(0);
conv_utf8_2_platform_encoding(zip_path, filepath);
utf8_clear(filepath);
utf8_append_c(filepath, name_arr->arr_body);
ByteBuf *name = bytebuf_create(0);
//conv_utf8_2_platform_encoding(name, filepath);

ret = zip_get_file_unzip_size(zip_path->buf, utf8_cstr(filepath));
ret = zip_get_file_unzip_size(zip_path_arr->arr_body, name_arr->arr_body);

bytebuf_destory(zip_path);
bytebuf_destory(name);
utf8_destory(filepath);
}
push_long(runtime->stack, ret);
#if _JVM_DEBUG_LOG_LEVEL > 5
Expand All @@ -1519,26 +1499,14 @@ s32 org_mini_zip_ZipFile_getEntry0(Runtime *runtime, JClass *clazz) {
Instance *name_arr = localvar_getRefer(runtime->localvar, 1);
s32 ret = -1;
if (zip_path_arr && name_arr) {
Utf8String *filepath = utf8_create_c(zip_path_arr->arr_body);
ByteBuf *zip_path = bytebuf_create(0);
conv_utf8_2_platform_encoding(zip_path, filepath);
utf8_clear(filepath);
utf8_append_c(filepath, name_arr->arr_body);
ByteBuf *name = bytebuf_create(0);
//conv_utf8_2_platform_encoding(name, filepath);

s64 filesize = zip_get_file_unzip_size(zip_path->buf, utf8_cstr(filepath));
s64 filesize = zip_get_file_unzip_size(zip_path_arr->arr_body, name_arr->arr_body);
if (filesize >= 0) {
Instance *arr = jarray_create_by_type_index(runtime, (s32) filesize, DATATYPE_BYTE);
ret = zip_loadfile_to_mem(zip_path->buf, utf8_cstr(filepath), arr->arr_body, filesize);
ret = zip_loadfile_to_mem(zip_path_arr->arr_body, name_arr->arr_body, arr->arr_body, filesize);
if (ret == 0) {
push_ref(runtime->stack, arr);
}
}

bytebuf_destory(zip_path);
bytebuf_destory(name);
utf8_destory(filepath);
}
if (ret) {
push_ref(runtime->stack, NULL);
Expand All @@ -1556,20 +1524,10 @@ s32 org_mini_zip_ZipFile_putEntry0(Runtime *runtime, JClass *clazz) {
Instance *content_arr = localvar_getRefer(runtime->localvar, 2);
s32 ret = -1;
if (zip_path_arr && name_arr) {
Utf8String *filepath = utf8_create_c(zip_path_arr->arr_body);
ByteBuf *zip_path = bytebuf_create(0);
conv_utf8_2_platform_encoding(zip_path, filepath);
utf8_clear(filepath);
utf8_append_c(filepath, name_arr->arr_body);
ByteBuf *name = bytebuf_create(0);
//conv_utf8_2_platform_encoding(name, filepath);

zip_savefile_mem(zip_path->buf, utf8_cstr(filepath), content_arr ? content_arr->arr_body : NULL, content_arr ? content_arr->arr_length : 0);
zip_savefile_mem(zip_path_arr->arr_body, name_arr->arr_body, content_arr ? content_arr->arr_body : NULL, content_arr ? content_arr->arr_length : 0);
ret = 0;

bytebuf_destory(zip_path);
bytebuf_destory(name);
utf8_destory(filepath);
}
push_int(runtime->stack, ret);
#if _JVM_DEBUG_LOG_LEVEL > 5
Expand All @@ -1584,14 +1542,9 @@ s32 org_mini_zip_ZipFile_fileCount0(Runtime *runtime, JClass *clazz) {

s32 ret = 0;
if (zip_path_arr) {
Utf8String *filepath = utf8_create_c(zip_path_arr->arr_body);
ByteBuf *zip_path = bytebuf_create(0);
conv_utf8_2_platform_encoding(zip_path, filepath);

ret = zip_filecount(zip_path->buf);
ret = zip_filecount(zip_path_arr->arr_body);

bytebuf_destory(zip_path);
utf8_destory(filepath);
}
push_int(runtime->stack, ret);
#if _JVM_DEBUG_LOG_LEVEL > 5
Expand All @@ -1605,11 +1558,8 @@ s32 org_mini_zip_ZipFile_listFiles0(Runtime *runtime, JClass *clazz) {
Instance *zip_path_arr = localvar_getRefer(runtime->localvar, 0);
s32 ret = -1;
if (zip_path_arr) {
Utf8String *filepath = utf8_create_c(zip_path_arr->arr_body);
ByteBuf *zip_path = bytebuf_create(0);
conv_utf8_2_platform_encoding(zip_path, filepath);

ArrayList *list = zip_get_filenames(zip_path->buf);
ArrayList *list = zip_get_filenames(zip_path_arr->arr_body);
if (list) {
Utf8String *clustr = utf8_create_c(STR_CLASS_JAVA_LANG_STRING);
Instance *jarr = jarray_create_by_type_name(runtime, list->length, clustr, NULL);
Expand All @@ -1627,8 +1577,6 @@ s32 org_mini_zip_ZipFile_listFiles0(Runtime *runtime, JClass *clazz) {
ret = 0;
}

bytebuf_destory(zip_path);
utf8_destory(filepath);
}
if (ret == -1) {
push_ref(runtime->stack, NULL);
Expand All @@ -1645,14 +1593,9 @@ s32 org_mini_zip_ZipFile_isDirectory0(Runtime *runtime, JClass *clazz) {
s32 index = localvar_getInt(runtime->localvar, 1);
s32 ret = -1;
if (zip_path_arr) {
Utf8String *filepath = utf8_create_c(zip_path_arr->arr_body);
ByteBuf *zip_path = bytebuf_create(0);
conv_utf8_2_platform_encoding(zip_path, filepath);

ret = zip_is_directory(zip_path->buf, index);
ret = zip_is_directory(zip_path_arr->arr_body, index);

bytebuf_destory(zip_path);
utf8_destory(filepath);
}

push_int(runtime->stack, ret);
Expand Down
24 changes: 19 additions & 5 deletions minijvm/c/jvm/jni_std.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,8 +628,8 @@ s32 java_lang_Object_wait(Runtime *runtime, JClass *clazz) {
invoke_deepth(runtime);
jvm_printf("java_lang_Object_wait %llx wait %lld\n", (s64) (intptr_t) ins, l2d.l);
#endif
jthread_waitTime(&ins->mb, runtime, l2d.l);
return 0;
s32 ret = jthread_waitTime(&ins->mb, runtime, l2d.l);
return ret;
}

s32 java_lang_Runtime_exitInternal(Runtime *runtime, JClass *clazz) {
Expand Down Expand Up @@ -1206,8 +1206,8 @@ s32 java_lang_Thread_sleep(Runtime *runtime, JClass *clazz) {
invoke_deepth(runtime);
jvm_printf("java_lang_Thread_sleep %lld\n", l2d.l);
#endif
jthread_sleep(runtime, l2d.l);
return 0;
s32 ret = jthread_sleep(runtime, l2d.l);
return ret;
}

s32 java_lang_Thread_start(Runtime *runtime, JClass *clazz) {
Expand Down Expand Up @@ -1270,7 +1270,13 @@ s32 java_lang_Thread_interrupt0(Runtime *runtime, JClass *clazz) {
Instance *ins = (Instance *) localvar_getRefer(runtime->localvar, 0);

Runtime *rt_thread = jthread_get_stackframe_value(runtime->jvm, ins);
rt_thread->thrd_info->is_interrupt = 1;
if (rt_thread) {
rt_thread->thrd_info->is_interrupt = 1;

if (rt_thread->thrd_info->thread_status == THREAD_STATUS_WAIT) {
jthread_wakeup(rt_thread);
}
}
#if _JVM_DEBUG_LOG_LEVEL > 5
invoke_deepth(runtime);
jvm_printf("java_lang_Thread_interrupt0 \n");
Expand All @@ -1279,6 +1285,13 @@ s32 java_lang_Thread_interrupt0(Runtime *runtime, JClass *clazz) {
return 0;
}

s32 java_lang_Thread_interrupted(Runtime *runtime, JClass *clazz) {

push_int(runtime->stack, runtime->thrd_info->is_interrupt != 0);

return 0;
}

s32 java_lang_Thread_setContextClassLoader0(Runtime *runtime, JClass *clazz) {
RuntimeStack *stack = runtime->stack;
Instance *ins_thread = (Instance *) localvar_getRefer(runtime->localvar, 0);
Expand Down Expand Up @@ -1538,6 +1551,7 @@ static java_native_method METHODS_STD_TABLE[] = {
{"java/lang/Thread", "activeCount", "()I", java_lang_Thread_activeCount},
{"java/lang/Thread", "setPriority0", "(I)V", java_lang_Thread_setPriority0},
{"java/lang/Thread", "interrupt0", "()V", java_lang_Thread_interrupt0},
{"java/lang/Thread", "interrupted", "()V", java_lang_Thread_interrupted},
{"java/lang/Thread", "setContextClassLoader0", "(Ljava/lang/ClassLoader;)V", java_lang_Thread_setContextClassLoader0},
{"java/lang/Thread", "getContextClassLoader0", "()Ljava/lang/ClassLoader;", java_lang_Thread_getContextClassLoader0},
{"java/lang/Throwable", "printStackTrace0", "", java_io_Throwable_printStackTrace0},
Expand Down
8 changes: 7 additions & 1 deletion minijvm/c/jvm/jvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,13 +316,19 @@ s32 jvm_init(MiniJVM *jvm, c8 *p_bootclasspath, c8 *p_classpath) {
jvm_printf("[ERROR]maybe bootstrap classpath misstake: %s \n", p_bootclasspath);
return -1;
}
//load bootstrap class
utf8_clear(clsName);
utf8_append_c(clsName, STR_CLASS_JAVA_LANG_THREAD);
classes_load_get(NULL, clsName, runtime);

utf8_clear(clsName);
utf8_append_c(clsName, STR_CLASS_SUN_MISC_LAUNCHER);
classes_load_get(NULL, clsName, runtime);
//开始装载类
//for interrupted thread
utf8_clear(clsName);
utf8_append_c(clsName, STR_CLASS_JAVA_LANG_INTERRUPTEDEXCEPTION);//must load this class ,because it will be used when thread interrupt ,but it can not load when that thread is marked as interrupted
JClass *c2 = classes_load_get(NULL, clsName, runtime);
Instance *interruptedException = instance_create(runtime, c);
utf8_destory(clsName);
gc_move_objs_thread_2_gc(runtime);
runtime_destory(runtime);
Expand Down
7 changes: 5 additions & 2 deletions minijvm/c/jvm/jvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ extern "C" {

//======================= micro define =============================
//_JVM_DEBUG 01=thread info, 02=garage&jit info , 03=class load, 04=method call, 06=all bytecode
#define _JVM_DEBUG_LOG_LEVEL 01
#define _JVM_DEBUG_LOG_LEVEL 02
#define _JVM_DEBUG_LOG_TO_FILE 0
#define _JVM_DEBUG_GARBAGE_DUMP 0
#define _JVM_DEBUG_PROFILE 0
Expand Down Expand Up @@ -456,6 +456,7 @@ enum {
JVM_EXCEPTION_CLASSCAST,
JVM_EXCEPTION_ARRAYINDEXOUTOFBOUNDS,
JVM_EXCEPTION_INSTANTIATION,
JVM_EXCEPTION_INTERRUPTED,
};

enum {
Expand All @@ -479,6 +480,7 @@ extern c8 const *STR_CLASS_JAVA_LANG_DOUBLE;
extern c8 const *STR_CLASS_JAVA_LANG_FLOAT;
extern c8 const *STR_CLASS_JAVA_LANG_OBJECT;
extern c8 const *STR_CLASS_JAVA_LANG_THREAD;
extern c8 const *STR_CLASS_JAVA_LANG_INTERRUPTEDEXCEPTION;
extern c8 const *STR_CLASS_JAVA_LANG_CLASS;
extern c8 const *STR_CLASS_JAVA_LANG_CLASSLOADER;
extern c8 const *STR_CLASS_JAVA_LANG_REF_REFERENCE;
Expand Down Expand Up @@ -1263,7 +1265,8 @@ struct _JavaThreadInfo {
u8 volatile is_suspend;
u8 volatile is_unparked;
u8 volatile is_blocking;// some of native method will enter blocking state
u8 is_interrupt;
u8 is_stop; //thread is marked as stop status, need set is_interrupt=1 also
u8 is_interrupt; //thread is marked as interrupt, set by Thread.interrupt();
u8 type;// gc /jdwp /normal

thrd_t pthread;
Expand Down
27 changes: 22 additions & 5 deletions minijvm/c/jvm/jvm_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ void thread_stop_all(MiniJVM *jvm) {

jthread_suspend(r);
r->thrd_info->no_pause = 1;
r->thrd_info->is_interrupt = 1;
r->thrd_info->is_stop = 1;
MemoryBlock *tl = r->thrd_info->curThreadLock;
if (tl) {
jthread_lock(tl, r);
Expand Down Expand Up @@ -1100,12 +1100,20 @@ s32 jthread_waitTime(MemoryBlock *mb, Runtime *runtime, s64 waitms) {
runtime->thrd_info->thread_status = thread_status;
runtime->thrd_info->curThreadLock = NULL;
jthread_block_exit(runtime);
return check_throw_interruptexception(runtime);
}

//if the thread is waiting , wake it up
s32 jthread_wakeup(Runtime *runtime) {
MemoryBlock *tl = runtime->thrd_info->curThreadLock;
jthread_lock(tl, runtime);
jthread_notify(tl, runtime);
jthread_unlock(tl, runtime);
return 0;
}

s32 jthread_sleep(Runtime *runtime, s64 ms) {
static const s64 PERIOD = 500;
s32 ret = 0;
jthread_block_enter(runtime);
u8 thread_status = runtime->thrd_info->thread_status;
runtime->thrd_info->thread_status = THREAD_STATUS_SLEEPING;
Expand All @@ -1117,15 +1125,24 @@ s32 jthread_sleep(Runtime *runtime, s64 ms) {
remain = ms - sleeped;
threadSleep(remain < PERIOD ? remain : PERIOD);
sleeped += PERIOD;
if (runtime->thrd_info->is_interrupt) {
ret = 1;
if (runtime->thrd_info->is_interrupt || runtime->thrd_info->is_stop) {
break;
}
}
}
runtime->thrd_info->thread_status = thread_status;
jthread_block_exit(runtime);
return ret;
return check_throw_interruptexception(runtime);;
}

s32 check_throw_interruptexception(Runtime *runtime) {
if (!runtime->thrd_info->is_interrupt) {
return RUNTIME_STATUS_NORMAL;
}
runtime->thrd_info->is_interrupt = 0;
Instance *exception = exception_create(JVM_EXCEPTION_INTERRUPTED, runtime);
push_ref(runtime->stack, (__refer) exception);
return RUNTIME_STATUS_EXCEPTION;
}

s32 check_suspend_and_pause(Runtime *runtime) {
Expand Down
4 changes: 4 additions & 0 deletions minijvm/c/jvm/jvm_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,8 @@ s32 jthread_notifyAll(MemoryBlock *mb, Runtime *runtime);

s32 jthread_waitTime(MemoryBlock *mb, Runtime *runtime, s64 waitms);

s32 jthread_wakeup(Runtime *runtime);

s32 jthread_sleep(Runtime *runtime, s64 ms);

s32 jthread_yield(Runtime *runtime);
Expand All @@ -285,6 +287,8 @@ void jthread_block_exit(Runtime *runtime);

void jthread_block_enter(Runtime *runtime);

s32 check_throw_interruptexception(Runtime *runtime);

s32 check_suspend_and_pause(Runtime *runtime);

void thread_lock_dispose(ThreadLock *lock);
Expand Down
Loading

0 comments on commit 7c185af

Please sign in to comment.