Index: vm/thread/src/thread_native_thin_monitor.c =================================================================== --- vm/thread/src/thread_native_thin_monitor.c (revision 606208) +++ vm/thread/src/thread_native_thin_monitor.c (working copy) @@ -312,6 +312,10 @@ if (RECURSION(lockword) == MAX_RECURSION) { //inflate lock in case of recursion overflow fat_monitor = hythread_inflate_lock(lockword_ptr); + + if (fat_monitor == NULL) { + return TM_ERROR_OUT_OF_MEMORY; + } return hythread_monitor_try_enter(fat_monitor); //break FAT_LOCK; } else { @@ -427,7 +431,11 @@ return TM_ERROR_NONE; } TRACE(("inflate_contended thin_lcok%d\n", ++inflate_contended)); - hythread_inflate_lock(lockword_ptr); + fat_monitor = hythread_inflate_lock(lockword_ptr); + + if (fat_monitor == NULL) { + return TM_ERROR_OUT_OF_MEMORY; + } return TM_ERROR_NONE; } @@ -514,6 +522,9 @@ TRACE(("inflate_wait%d\n", ++inflate_waited)); // if it is not a thin lock, inflate it fat_monitor = hythread_inflate_lock(lockword_ptr); + if (fat_monitor == NULL) { + return TM_ERROR_OUT_OF_MEMORY; + } } else { // otherwise, get the appropriate fat lock fat_monitor = locktable_get_fat_monitor(FAT_LOCK_ID(lockword)); @@ -667,7 +678,10 @@ TRACE (("inflation begin for %x thread: %d", lockword, tm_self_tls->thread_id)); status = hythread_monitor_init(&fat_monitor, 0); // allocate fat fat_monitor - assert(status == TM_ERROR_NONE); + //assert(status == TM_ERROR_NONE); + if (status != TM_ERROR_NONE) { + return NULL; + } status = hythread_monitor_enter(fat_monitor); if (status != TM_ERROR_NONE) { return NULL; Index: vm/vmcore/include/object_handles.h =================================================================== --- vm/vmcore/include/object_handles.h (revision 606208) +++ vm/vmcore/include/object_handles.h (working copy) @@ -47,9 +47,10 @@ * during garbage collection. Note, GC suspension must be disabled when created or deleting * a frame and when adding objects or managed pointers. */ +#define GC_FRAME_DEFAULT_SIZE 10 class GcFrame { public: - GcFrame(unsigned size_hint = 0); + GcFrame(); ~GcFrame(); void add_object(ManagedObject**); @@ -60,7 +61,17 @@ private: void ensure_capacity(); - struct GcFrameNode* nodes; + + // A GcFrameNode contains capacity elements which can hold either objects references or managed pointers. + // The objects come first, ie, from index 0 to obj_size-1 + // The managed pointers come last, ie, from index obj_size to obj_size+mp_size-1 + // Inv: obj_size+mp_size<=capacity + struct GcFrameNode { + unsigned obj_size, mp_size, capacity; + GcFrameNode* next; + void** elements[GC_FRAME_DEFAULT_SIZE]; // Objects go several first, then managed pointers + } firstSetOfNodes; + GcFrameNode* nodes; GcFrame* next; }; @@ -139,6 +150,7 @@ * Creates global handle, which needs to be explicitly freed. */ ObjectHandle oh_allocate_global_handle(); +ObjectHandle oh_allocate_global_handle_from_jni(); /** * Frees global handle. */ Index: vm/vmcore/include/environment.h =================================================================== --- vm/vmcore/include/environment.h (revision 606208) +++ vm/vmcore/include/environment.h (working copy) @@ -142,6 +142,21 @@ String* Clonable_String; String* Serializable_String; + String* Detach_String; + String* DetachDescriptor_String; + String* GetUncaughtExceptionHandler_String; + String* GetUncaughtExceptionHandlerDescriptor_String; + String* UncaughtException_String; + String* UncaughtExceptionDescriptor_String; + String* GetDefaultUncaughtExceptionHandler_String; + String* GetDefaultUncaughtExceptionHandlerDescriptor_String; + String* GetName_String; + String* GetNameDescriptor_String; + String* Remove_String; + String* RemoveDescriptor_String; + String* LLRemove_String; + String* LLRemoveDescriptor_String; + String* JavaLangReflectMethod_String; String* JavaLangNullPointerException_String; String* JavaLangUnsatisfiedLinkError_String; @@ -227,6 +242,7 @@ Class* java_lang_Cloneable_Class; Class* java_lang_Thread_Class; Class* java_lang_ThreadGroup_Class; + Class* java_util_LinkedList_Class; Class* java_util_Date_Class; Class* java_util_Properties_Class; Class* java_lang_Runtime_Class; Index: vm/vmcore/src/jni/jni_array.cpp =================================================================== --- vm/vmcore/src/jni/jni_array.cpp (revision 606208) +++ vm/vmcore/src/jni/jni_array.cpp (working copy) @@ -362,6 +362,11 @@ } else { jboolean *primitive_array = (jboolean *)STD_MALLOC(sizeof(jboolean) * length); + if (primitive_array == NULL) { + exn_raise_by_name("java/lang/OutOfMemoryError"); + return NULL; + } + tmn_suspend_disable(); //---------------------------------v Vector_Handle java_array = (Vector_Handle)h->object; @@ -405,6 +410,11 @@ } else { jbyte *primitive_array = (jbyte *)STD_MALLOC(sizeof(jbyte) * length); + if (primitive_array == NULL) { + exn_raise_by_name("java/lang/OutOfMemoryError"); + return NULL; + } + tmn_suspend_disable(); //---------------------------------v Vector_Handle java_array = (Vector_Handle)h->object; @@ -448,6 +458,11 @@ } else { jchar *primitive_array = (jchar *)STD_MALLOC(sizeof(jchar) * length); + if (primitive_array == NULL) { + exn_raise_by_name("java/lang/OutOfMemoryError"); + return NULL; + } + tmn_suspend_disable(); //---------------------------------v Vector_Handle java_array = (Vector_Handle)h->object; @@ -491,6 +506,11 @@ } else { jshort *primitive_array = (jshort *)STD_MALLOC(sizeof(jshort) * length); + if (primitive_array == NULL) { + exn_raise_by_name("java/lang/OutOfMemoryError"); + return NULL; + } + tmn_suspend_disable(); //---------------------------------v Vector_Handle java_array = (Vector_Handle)h->object; @@ -535,6 +555,11 @@ jint *primitive_array = (jint *)STD_MALLOC(sizeof(jint) * length); + if (primitive_array == NULL) { + exn_raise_by_name("java/lang/OutOfMemoryError"); + return NULL; + } + tmn_suspend_disable(); //---------------------------------v Vector_Handle java_array = (Vector_Handle)h->object; @@ -578,6 +603,11 @@ } else { jlong *primitive_array = (jlong *)STD_MALLOC(sizeof(jlong) * length); + if (primitive_array == NULL) { + exn_raise_by_name("java/lang/OutOfMemoryError"); + return NULL; + } + tmn_suspend_disable(); //---------------------------------v Vector_Handle java_array = (Vector_Handle)h->object; @@ -622,6 +652,11 @@ jfloat *primitive_array = (jfloat *)STD_MALLOC(sizeof(jfloat) * length); + if (primitive_array == NULL) { + exn_raise_by_name("java/lang/OutOfMemoryError"); + return NULL; + } + tmn_suspend_disable(); //---------------------------------v Vector_Handle java_array = (Vector_Handle)h->object; @@ -665,6 +700,11 @@ } else { jdouble *primitive_array = (jdouble *)STD_MALLOC(sizeof(jdouble) * length); + if (primitive_array == NULL) { + exn_raise_by_name("java/lang/OutOfMemoryError"); + return NULL; + } + tmn_suspend_disable(); //---------------------------------v Vector_Handle java_array = (Vector_Handle)h->object; Index: vm/vmcore/src/jni/jni.cpp =================================================================== --- vm/vmcore/src/jni/jni.cpp (revision 606208) +++ vm/vmcore/src/jni/jni.cpp (working copy) @@ -829,12 +829,17 @@ if (exn_raised() || !obj) return NULL; - if(!obj) { - return 0; + if(obj == NULL) { + return NULL; } assert(hythread_is_suspend_enabled()); - ObjectHandle new_handle = oh_allocate_global_handle(); + ObjectHandle new_handle = oh_allocate_global_handle_from_jni(); + + if (new_handle == NULL) { + return NULL; + } + ObjectHandle old_handle = (ObjectHandle)obj; tmn_suspend_disable(); //---------------------------------v Index: vm/vmcore/src/jit/jit_runtime_support.cpp =================================================================== --- vm/vmcore/src/jit/jit_runtime_support.cpp (revision 606208) +++ vm/vmcore/src/jit/jit_runtime_support.cpp (working copy) @@ -194,6 +194,10 @@ static NativeCodePtr addr = NULL; if (!addr) { + const unsigned cap_off = (unsigned)(POINTER_SIZE_INT)&((ObjectHandlesNew*)0)->capacity; + const POINTER_SIZE_INT next_off = (POINTER_SIZE_INT)&((ObjectHandlesNew*)0)->next; + const unsigned handles_size = (unsigned)(sizeof(ObjectHandlesNew)+sizeof(ManagedObject*)*16); + const unsigned cap_and_size = (unsigned)((0<<16) | 16); ManagedObject* (*p_instantiate_ref)(Class*,unsigned) = rth_ldc_ref_helper; LilCodeStub* cs = lil_parse_code_stub("entry 0:stdcall:pint,g4:ref;"); assert(cs); @@ -201,7 +205,8 @@ cs = lil_parse_onto_end(cs, "inc [%0i:pint];", dyn_count); assert(cs); } - cs = lil_parse_onto_end(cs, +#ifdef _IPF_ + cs = lil_parse_onto_end(cs, "push_m2n 0, %0i;" "in2out platform:ref;" "call %1i;" @@ -209,6 +214,22 @@ "ret;", (POINTER_SIZE_INT)FRAME_POPABLE, p_instantiate_ref); +#else + cs = lil_parse_onto_end(cs, + "push_m2n 0, %0i, handles;" + "locals 1;" + "alloc l0, %1i;" + "st[l0+%2i:g4], %3i;" + "st[l0+%4i:pint], 0;" + "handles=l0;" + "in2out platform:ref;" + "call %5i;" + "pop_m2n;" + "ret;", + (POINTER_SIZE_INT)FRAME_POPABLE, + handles_size, cap_off, cap_and_size, next_off, + p_instantiate_ref); +#endif assert(cs && lil_is_valid(cs)); addr = LilCodeGenerator::get_platform()->compile(cs); @@ -1787,6 +1808,11 @@ { LilCodeStub* cs = NULL; const char* in2out = NULL; + const unsigned cap_off = (unsigned)(POINTER_SIZE_INT)&((ObjectHandlesNew*)0)->capacity; + const POINTER_SIZE_INT next_off = (POINTER_SIZE_INT)&((ObjectHandlesNew*)0)->next; + const unsigned handles_size = (unsigned)(sizeof(ObjectHandlesNew)+sizeof(ManagedObject*)*8); + const unsigned cap_and_size = (unsigned)((0<<16) | 8); + if (type == ResolveResType_Unmanaged) { cs = lil_parse_code_stub("entry 0:stdcall:pint,pint:pint;"); in2out = "in2out platform:pint;"; @@ -1800,9 +1826,22 @@ cs = lil_parse_onto_end(cs, "inc [%0i:pint];", dyn_count); assert(cs); } - +#ifdef _IPF_ cs = lil_parse_onto_end(cs, "push_m2n 0, %0i;", (POINTER_SIZE_INT)(FRAME_POPABLE)); +#else + cs = lil_parse_onto_end(cs, "push_m2n 0, %0i, handles;", (POINTER_SIZE_INT)(FRAME_POPABLE)); assert(cs); + cs = lil_parse_onto_end(cs, + "locals 1;" + "alloc l0, %0i;" + "st[l0+%1i:g4], %2i;" + "st[l0+%3i:pint], 0;" + "handles=l0;", + handles_size, + cap_off, cap_and_size, + next_off); +#endif + assert(cs); cs = lil_parse_onto_end(cs, in2out); assert(cs); cs = lil_parse_onto_end(cs, @@ -1826,6 +1865,11 @@ { LilCodeStub* cs = NULL; const char* in2out = NULL; + const unsigned cap_off = (unsigned)(POINTER_SIZE_INT)&((ObjectHandlesNew*)0)->capacity; + const POINTER_SIZE_INT next_off = (POINTER_SIZE_INT)&((ObjectHandlesNew*)0)->next; + const unsigned handles_size = (unsigned)(sizeof(ObjectHandlesNew)+sizeof(ManagedObject*)*8); + const unsigned cap_and_size = (unsigned)((0<<16) | 8); + if (type == ResolveResType_Unmanaged) { cs = lil_parse_code_stub("entry 0:stdcall:pint,pint,ref:pint;"); in2out = "in2out platform:pint;"; @@ -1841,8 +1885,22 @@ assert(cs); } +#ifdef _IPF_ cs = lil_parse_onto_end(cs, "push_m2n 0, %0i;", (POINTER_SIZE_INT)(FRAME_POPABLE)); +#else + cs = lil_parse_onto_end(cs, "push_m2n 0, %0i, handles;", (POINTER_SIZE_INT)(FRAME_POPABLE)); assert(cs); + cs = lil_parse_onto_end(cs, + "locals 1;" + "alloc l0, %0i;" + "st[l0+%1i:g4], %2i;" + "st[l0+%3i:pint], 0;" + "handles=l0;", + handles_size, + cap_off, cap_and_size, + next_off); +#endif + assert(cs); cs = lil_parse_onto_end(cs, in2out); assert(cs); cs = lil_parse_onto_end(cs, @@ -1865,6 +1923,11 @@ { LilCodeStub* cs = NULL; const char* in2out = NULL; + const unsigned cap_off = (unsigned)(POINTER_SIZE_INT)&((ObjectHandlesNew*)0)->capacity; + const POINTER_SIZE_INT next_off = (POINTER_SIZE_INT)&((ObjectHandlesNew*)0)->next; + const unsigned handles_size = (unsigned)(sizeof(ObjectHandlesNew)+sizeof(ManagedObject*)*8); + const unsigned cap_and_size = (unsigned)((0<<16) | 8); + if (type == ResolveResType_Unmanaged) { cs = lil_parse_code_stub("entry 0:stdcall:pint,pint,pint:pint;"); in2out = "in2out platform:pint;"; @@ -1880,8 +1943,22 @@ assert(cs); } +#ifdef _IPF_ cs = lil_parse_onto_end(cs, "push_m2n 0, %0i;", (POINTER_SIZE_INT)(FRAME_POPABLE)); +#else + cs = lil_parse_onto_end(cs, "push_m2n 0, %0i, handles;", (POINTER_SIZE_INT)(FRAME_POPABLE)); assert(cs); + cs = lil_parse_onto_end(cs, + "locals 1;" + "alloc l0, %0i;" + "st[l0+%1i:g4], %2i;" + "st[l0+%3i:pint], 0;" + "handles=l0;", + handles_size, + cap_off, cap_and_size, + next_off); +#endif + assert(cs); cs = lil_parse_onto_end(cs, in2out); assert(cs); cs = lil_parse_onto_end(cs, Index: vm/vmcore/src/jit/compile.cpp =================================================================== --- vm/vmcore/src/jit/compile.cpp (revision 606208) +++ vm/vmcore/src/jit/compile.cpp (working copy) @@ -783,6 +783,10 @@ GcFrame gc; compile_protect_arguments(method, &gc); + if (exn_raised()) { + return NULL; + } + tmn_suspend_enable(); if (method->is_abstract()) { compile_raise_exception("java/lang/AbstractMethodError", "", method); Index: vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp =================================================================== --- vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp (revision 606208) +++ vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp (working copy) @@ -250,9 +250,16 @@ JNIEXPORT jobject JNICALL Java_org_apache_harmony_vm_VMStack_getStackState (JNIEnv *jenv, jclass) { + assert(hythread_is_suspend_enabled()); unsigned size; StackTraceFrame* frames; st_get_trace(get_thread_ptr(), &size, &frames); + + if (frames == NULL) { + exn_raise_object(VM_Global_State::loader_env->java_lang_OutOfMemoryError); + return 0; + } + assert(frames); unsigned data_size = size * sizeof(StackTraceFrame); // pack trace into long[] array Index: vm/vmcore/src/class_support/C_Interface.cpp =================================================================== --- vm/vmcore/src/class_support/C_Interface.cpp (revision 606208) +++ vm/vmcore/src/class_support/C_Interface.cpp (working copy) @@ -1736,6 +1736,13 @@ Method_Signature *ms = m->get_method_sig(); if(!ms) { ms = new Method_Signature(); + + if (ms == NULL) { + exn_raise_object(VM_Global_State::loader_env->java_lang_OutOfMemoryError); + return NULL; + } + + assert(ms); ms->initialize_from_method(m); m->set_method_sig(ms); } Index: vm/vmcore/src/class_support/Environment.cpp =================================================================== --- vm/vmcore/src/class_support/Environment.cpp (revision 606208) +++ vm/vmcore/src/class_support/Environment.cpp (working copy) @@ -94,6 +94,21 @@ EnqueueName_String = string_pool.lookup("enqueue"); Clonable_String = string_pool.lookup("java/lang/Cloneable"); Serializable_String = string_pool.lookup("java/io/Serializable"); + + Detach_String = string_pool.lookup("detach"); + DetachDescriptor_String = string_pool.lookup("(Ljava/lang/Throwable;)V"); + GetUncaughtExceptionHandler_String = string_pool.lookup("getUncaughtExceptionHandler"); + GetUncaughtExceptionHandlerDescriptor_String = string_pool.lookup("()Ljava/lang/Thread$UncaughtExceptionHandler;"); + UncaughtException_String = string_pool.lookup("uncaughtException"); + UncaughtExceptionDescriptor_String = string_pool.lookup("(Ljava/lang/Thread;Ljava/lang/Throwable;)V"); + GetDefaultUncaughtExceptionHandler_String = string_pool.lookup("getDefaultUncaughtExceptionHandler"); + GetDefaultUncaughtExceptionHandlerDescriptor_String = string_pool.lookup("()Ljava/lang/Thread$UncaughtExceptionHandler;"); + GetName_String = string_pool.lookup("getName"); + GetNameDescriptor_String = string_pool.lookup("()Ljava/lang/String;"); + Remove_String = string_pool.lookup("remove"); + RemoveDescriptor_String = string_pool.lookup("(Ljava/lang/Thread;)V"); + LLRemove_String = string_pool.lookup("remove"); + LLRemoveDescriptor_String = string_pool.lookup("(Ljava/lang/Object;)Z"); Length_String = string_pool.lookup("length"); LoadClass_String = string_pool.lookup("loadClass"); Index: vm/vmcore/src/init/vm_init.cpp =================================================================== --- vm/vmcore/src/init/vm_init.cpp (revision 606208) +++ vm/vmcore/src/init/vm_init.cpp (working copy) @@ -468,6 +468,8 @@ preload_class(vm_env, "java/lang/Thread"); vm_env->java_lang_ThreadGroup_Class = preload_class(vm_env, "java/lang/ThreadGroup"); + vm_env->java_util_LinkedList_Class = + preload_class(vm_env, "java/util/LinkedList"); vm_env->java_util_Date_Class = preload_class(vm_env, "java/util/Date"); vm_env->java_util_Properties_Class = @@ -869,8 +871,50 @@ hythread_suspend_enable(); + Method * m; + + // pre compile detach and all includes + if (!interpreter_enabled()) { + m = vm_env->java_lang_Thread_Class->lookup_method( + vm_env->Detach_String, vm_env->DetachDescriptor_String); + assert(m); + vm_env->em_interface->CompileMethod(m); + + m = vm_env->java_lang_Thread_Class->lookup_method( + vm_env->GetUncaughtExceptionHandler_String, + vm_env->GetUncaughtExceptionHandlerDescriptor_String); + assert(m); + vm_env->em_interface->CompileMethod(m); + + m = vm_env->java_lang_ThreadGroup_Class->lookup_method( + vm_env->UncaughtException_String, vm_env->UncaughtExceptionDescriptor_String); + assert(m); + vm_env->em_interface->CompileMethod(m); + + m = vm_env->java_lang_Thread_Class->lookup_method( + vm_env->GetDefaultUncaughtExceptionHandler_String, + vm_env->GetDefaultUncaughtExceptionHandlerDescriptor_String); + assert(m); + vm_env->em_interface->CompileMethod(m); + + m = vm_env->java_lang_Thread_Class->lookup_method( + vm_env->GetName_String, vm_env->GetNameDescriptor_String); + assert(m); + vm_env->em_interface->CompileMethod(m); + + m = vm_env->java_lang_ThreadGroup_Class->lookup_method( + vm_env->Remove_String, vm_env->RemoveDescriptor_String); + assert(m); + vm_env->em_interface->CompileMethod(m); + + m = vm_env->java_util_LinkedList_Class->lookup_method( + vm_env->LLRemove_String, vm_env->LLRemoveDescriptor_String); + assert(m); + vm_env->em_interface->CompileMethod(m); + } + // Mark j.l.Throwable() constructor as a side effects free. - Method * m = vm_env->java_lang_Throwable_Class->lookup_method( + m = vm_env->java_lang_Throwable_Class->lookup_method( vm_env->Init_String, vm_env->VoidVoidDescriptor_String); assert(m); m->set_side_effects(MSE_False); Index: vm/vmcore/src/stack/stack_trace.cpp =================================================================== --- vm/vmcore/src/stack/stack_trace.cpp (revision 606208) +++ vm/vmcore/src/stack/stack_trace.cpp (working copy) @@ -95,7 +95,9 @@ unsigned st_get_depth(VM_thread *p_vmthread) { ASSERT_NO_INTERPRETER - StackIterator* si = si_create_from_native(p_vmthread); + StackIterator* si = (StackIterator*) STD_ALLOCA(si_size()); + si_fill_from_native(si, p_vmthread); + unsigned depth = 0; while (!si_is_past_end(si)) { if (si_get_method(si)) { @@ -103,7 +105,6 @@ } si_goto_previous(si); } - si_free(si); return depth; } @@ -176,6 +177,14 @@ unsigned depth = st_get_depth(p_vmthread); StackTraceFrame* stf = st_alloc_frames(depth); + + if (stf == NULL) { + *res_depth = depth; + *stfs = NULL; + tmn_suspend_enable(); + return; + } + assert(stf); *res_depth = depth; *stfs = stf; Index: vm/vmcore/src/object/object_handles.cpp =================================================================== --- vm/vmcore/src/object/object_handles.cpp (revision 606208) +++ vm/vmcore/src/object/object_handles.cpp (working copy) @@ -52,36 +52,17 @@ ////////////////////////////////////////////////////////////////////////// // GC native interface -// A GcFrameNode contains capacity elements which can hold either objects references or managed pointers. -// The objects come first, ie, from index 0 to obj_size-1 -// The managed pointers come last, ie, from index obj_size to obj_size+mp_size-1 -// Inv: obj_size+mp_size<=capacity -struct GcFrameNode { - unsigned obj_size, mp_size, capacity; - GcFrameNode* next; - void** elements[1]; // Objects go first, then managed pointers -}; - -static GcFrameNode* gc_frame_node_new(unsigned capacity) +GcFrame::GcFrame() { - assert(capacity>0); - GcFrameNode* n = (GcFrameNode*)STD_MALLOC(sizeof(GcFrameNode)+(capacity-1)*sizeof(void**)); - assert(n); - n->capacity = capacity; - n->obj_size = 0; - n->mp_size = 0; - n->next = NULL; - return n; -} - -GcFrame::GcFrame(unsigned size_hint) -{ assert(!hythread_is_suspend_enabled()); - if (size_hint>0) - nodes = gc_frame_node_new(size_hint); - else - nodes = NULL; + nodes = &firstSetOfNodes; + + nodes->capacity = GC_FRAME_DEFAULT_SIZE; + nodes->obj_size = 0; + nodes->mp_size = 0; + nodes->next = NULL; + next = (GcFrame*)p_TLS_vmthread->gc_frames; p_TLS_vmthread->gc_frames = this; } @@ -95,7 +76,7 @@ next = NULL; GcFrameNode* c; GcFrameNode* n; - for(c=nodes; c; c=n) { + for(c=nodes; c->next; c=n) { n = c->next; STD_FREE(c); } @@ -149,7 +130,11 @@ void GcFrame::ensure_capacity() { if (!nodes || nodes->obj_size+nodes->mp_size >= nodes->capacity) { - GcFrameNode* n = gc_frame_node_new(10); + GcFrameNode* n = (GcFrameNode*)STD_MALLOC(sizeof(GcFrameNode)); + assert(n); + n->capacity = GC_FRAME_DEFAULT_SIZE; + n->obj_size = 0; + n->mp_size = 0; n->next = nodes; nodes = n; } @@ -207,12 +192,17 @@ static ObjectHandlesOld* global_object_handles = NULL; -ObjectHandle oh_allocate_global_handle() +static ObjectHandle oh_allocate_global_handle_internal() { Global_Env * vm_env = VM_Global_State::loader_env; // Allocate and init handle ObjectHandlesOld* h = oh_allocate_object_handle(); //(ObjectHandlesOld*)m_malloc(sizeof(ObjectHandlesOld)); + + if (h == NULL) { + return NULL; + } + h->handle.object = NULL; h->allocated_on_the_stack = false; @@ -229,6 +219,23 @@ return &h->handle; } //vm_create_global_object_handle +ObjectHandle oh_allocate_global_handle() +{ + ObjectHandle res = oh_allocate_global_handle_internal(); + assert(res); + return res; +} + +ObjectHandle oh_allocate_global_handle_from_jni() +{ + ObjectHandle res = oh_allocate_global_handle_internal(); + + if (res == NULL) { + exn_raise_object(VM_Global_State::loader_env->java_lang_OutOfMemoryError); + } + return res; +} + static bool UNUSED is_global_handle(ObjectHandle handle) { for(ObjectHandlesOld* g = global_object_handles; g; g=g->next) @@ -269,6 +276,11 @@ static ObjectHandlesOld* oh_allocate_object_handle() { ObjectHandlesOld* h = (ObjectHandlesOld*)STD_MALLOC(sizeof(ObjectHandlesOld)); + + if (h == NULL) { + return NULL; + } + assert(h); memset(h, 0, sizeof(ObjectHandlesOld)); return h; @@ -361,6 +373,9 @@ ObjectHandle NativeObjectHandles::allocate() { ObjectHandle res = oh_allocate_handle(&handles); + if (res == NULL) { + printf("GBPLTW"); + } assert(res); return res; } Index: vm/vmcore/src/thread/helpers/thread_helpers_ia32.cpp =================================================================== --- vm/vmcore/src/thread/helpers/thread_helpers_ia32.cpp (revision 606208) +++ vm/vmcore/src/thread/helpers/thread_helpers_ia32.cpp (working copy) @@ -27,6 +27,9 @@ #include #include #include "open/jthread.h" +#include "object_handles.h" +#include "port_malloc.h" +#include "m2n.h" #include @@ -152,6 +155,26 @@ return ss; } +static IDATA rt_jthread_monitor_enter(ManagedObject* monitor) { + const unsigned handles_size = (unsigned)(sizeof(ObjectHandlesNew)+sizeof(ManagedObject*)*4); + ObjectHandlesNew* handels = (ObjectHandlesNew *)STD_ALLOCA(handles_size); + handels->capacity = 4; + handels->size = 0; + handels->next = NULL; + + m2n_set_local_handles(m2n_get_last_frame(), (ObjectHandles *) handels); + + ObjectHandle monitorJavaObj = oh_allocate_local_handle(); + monitorJavaObj->object = monitor; + + IDATA result = jthread_monitor_enter(monitorJavaObj); + + free_local_object_handles2(m2n_get_local_handles(m2n_get_last_frame())); + m2n_set_local_handles(m2n_get_last_frame(), NULL); + + return result; +} + /** * Generates slow path of monitor enter. * This code could block on monitor and contains safepoint. @@ -169,7 +192,7 @@ } ss = push(ss, eax_opnd); // push the address of the handle - ss = call(ss, (char *)jthread_monitor_enter); + ss = call(ss, (char *)rt_jthread_monitor_enter); ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters return ss; } Index: vm/vmcore/src/thread/helpers/thread_helpers_em64t.cpp =================================================================== --- vm/vmcore/src/thread/helpers/thread_helpers_em64t.cpp (revision 606208) +++ vm/vmcore/src/thread/helpers/thread_helpers_em64t.cpp (working copy) @@ -32,6 +32,9 @@ #include #include #include "open/jthread.h" +#include "object_handles.h" +#include "port_malloc.h" +#include "m2n.h" #include @@ -155,6 +158,26 @@ return ss; } +static IDATA rt_jthread_monitor_enter(ManagedObject* monitor) { + const unsigned handles_size = (unsigned)(sizeof(ObjectHandlesNew)+sizeof(ManagedObject*)*4); + ObjectHandlesNew* handels = (ObjectHandlesNew *)STD_ALLOCA(handles_size); + handels->capacity = 4; + handels->size = 0; + handels->next = NULL; + + m2n_set_local_handles(m2n_get_last_frame(), (ObjectHandles *) handels); + + ObjectHandle monitorJavaObj = oh_allocate_local_handle(); + monitorJavaObj->object = monitor; + + IDATA result = jthread_monitor_enter(monitorJavaObj); + + free_local_object_handles2(m2n_get_local_handles(m2n_get_last_frame())); + m2n_set_local_handles(m2n_get_last_frame(), NULL); + + return result; +} + /** * Generates slow path of monitor enter. * This code could block on monitor and contains safepoint. @@ -171,7 +194,7 @@ ss = mov(ss, rdi_opnd, input_param1); } - ss = call(ss, (char *)jthread_monitor_enter); + ss = call(ss, (char *)rt_jthread_monitor_enter); return ss; } Index: vm/vmcore/src/util/em64t/base/jit_lock_rt_support_em64t.cpp =================================================================== --- vm/vmcore/src/util/em64t/base/jit_lock_rt_support_em64t.cpp (revision 606208) +++ vm/vmcore/src/util/em64t/base/jit_lock_rt_support_em64t.cpp (working copy) @@ -113,10 +113,7 @@ // Slow path: happens when the monitor is busy (contention case) ss = gen_setup_j2n_frame(ss); - - ss = call(ss, (char *)oh_convert_to_local_handle); - ss = gen_monitorenter_slow_path_helper(ss, rax_opnd); - + ss = gen_monitorenter_slow_path_helper(ss, rdi_opnd); ss = gen_pop_j2n_frame(ss); ss = ret(ss); Index: vm/vmcore/src/util/em64t/base/compile_em64t.cpp =================================================================== --- vm/vmcore/src/util/em64t/base/compile_em64t.cpp (revision 606208) +++ vm/vmcore/src/util/em64t/base/compile_em64t.cpp (working copy) @@ -72,7 +72,13 @@ assert(!hythread_is_suspend_enabled()); Method_Signature_Handle msh = method_get_signature(method); - + + if (msh == NULL) { + return; + } + + assert(msh); + unsigned num_gp_used = 0; #ifdef _WIN64 #define num_fp_used num_gp_used Index: vm/vmcore/src/util/vm_strings.cpp =================================================================== --- vm/vmcore/src/util/vm_strings.cpp (revision 606208) +++ vm/vmcore/src/util/vm_strings.cpp (working copy) @@ -267,7 +267,7 @@ VTable *jls_vtable = VM_Global_State::loader_env->JavaLangString_VTable; assert(!hythread_is_suspend_enabled()); - GcFrame gc(2); + GcFrame gc; gc.add_object((ManagedObject**)&array); ManagedObject* jls = (ManagedObject*)class_alloc_new_object_using_vtable(jls_vtable); Index: vm/vmcore/src/util/ia32/base/compile_IA32.cpp =================================================================== --- vm/vmcore/src/util/ia32/base/compile_IA32.cpp (revision 606208) +++ vm/vmcore/src/util/ia32/base/compile_IA32.cpp (working copy) @@ -82,6 +82,12 @@ void compile_protect_arguments(Method_Handle method, GcFrame* gc) { assert(!hythread_is_suspend_enabled()); Method_Signature_Handle msh = method_get_signature(method); + + if (msh == NULL) { + return; + } + + assert(msh); unsigned num_args = method_args_get_number(msh); unsigned num_arg_words = ((Method*)method)->get_num_arg_slots(); Index: vm/vmcore/src/util/ia32/base/jit_lock_rt_support_ia32.cpp =================================================================== --- vm/vmcore/src/util/ia32/base/jit_lock_rt_support_ia32.cpp (revision 606208) +++ vm/vmcore/src/util/ia32/base/jit_lock_rt_support_ia32.cpp (working copy) @@ -107,20 +107,16 @@ char *backpatch_address__fast_monitor_failed = ((char *)ss) - 1; ss = ret(ss, Imm_Opnd(4)); - // Slow path: happens when the monitor is busy (contention case) offset = (signed)ss - (signed)backpatch_address__fast_monitor_failed - 1; *backpatch_address__fast_monitor_failed = (char)offset; } + // Slow path: happens when the monitor is busy (contention case) ss = gen_setup_j2n_frame(ss); - ss = push(ss, M_Base_Opnd(esp_reg, m2n_sizeof_m2n_frame)); - - ss = call(ss, (char *)oh_convert_to_local_handle); - ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters - + ss = mov(ss, eax_opnd, M_Base_Opnd(esp_reg, m2n_sizeof_m2n_frame)); ss = gen_monitorenter_slow_path_helper(ss, eax_opnd); - ss = gen_pop_j2n_frame(ss); + ss = ret(ss, Imm_Opnd(4)); // Handle NPE here Index: vm/vmcore/src/util/ipf/base/compile_ipf.cpp =================================================================== --- vm/vmcore/src/util/ipf/base/compile_ipf.cpp (revision 606208) +++ vm/vmcore/src/util/ipf/base/compile_ipf.cpp (working copy) @@ -372,6 +372,12 @@ void compile_protect_arguments(Method_Handle method, GcFrame* gc) { assert(!hythread_is_suspend_enabled()); Method_Signature_Handle msh = method_get_signature(method); + + if (msh == NULL) { + return; + } + + assert(msh); unsigned num_args = method_args_get_number(msh); M2nFrame* m2nf = m2n_get_last_frame();