Index: gc_cc/src/init.cpp =================================================================== --- gc_cc/src/init.cpp (revision 589494) +++ gc_cc/src/init.cpp (working copy) @@ -28,6 +28,7 @@ #include "open/vm_gc.h" #include "open/gc.h" #include "jit_intf.h" +#include "jit_runtime_support.h" #include #include "gc_types.h" #include "cxxlog.h" @@ -291,6 +292,17 @@ assert(mark_bits != MEM_FAILURE); } +static void init_gc_helpers() +{ + set_property("vm.component.classpath.gc_ρρ", "gc_ρρ.jar", VM_PROPERTIES); + register_magic_helper(VM_RT_NEW_RESOLVED_USING_VTABLE_AND_SIZE, + "org/apache/harmony/drlvm/gc_gen/GCHelper", "alloc", + "(II)Lorg/vmmagic/unboxed/Address;"); + register_magic_helper(VM_RT_NEW_VECTOR_USING_VTABLE, + "org/apache/harmony/drlvm/gc_gen/GCHelper", "allocArray", + "(III)Lorg/vmmagic/unboxed/Address;"); +} + int gc_init() { INFO2("gc.init", "GC init called\n"); @@ -311,6 +323,8 @@ gc_end = apr_time_now(); timer_init(); + init_gc_helpers(); + return JNI_OK; } Index: gc_gen/src/common/gc_for_vm.cpp =================================================================== --- gc_gen/src/common/gc_for_vm.cpp (revision 589494) +++ gc_gen/src/common/gc_for_vm.cpp (working copy) @@ -22,6 +22,7 @@ #include #include "port_sysinfo.h" #include "vm_threads.h" +#include "jit_runtime_support.h" #include "compressed_ref.h" #include "../gen/gen.h" @@ -53,6 +54,17 @@ SPACE_ALLOC_UNIT = max(gc->_system_alloc_unit, GC_BLOCK_SIZE_BYTES); } +static void init_gc_helpers() +{ + set_property("vm.component.classpath.gc_gen", "gc_gen.jar", VM_PROPERTIES); + register_magic_helper(VM_RT_NEW_RESOLVED_USING_VTABLE_AND_SIZE, + "org/apache/harmony/drlvm/gc_gen/GCHelper", "alloc", + "(II)Lorg/vmmagic/unboxed/Address;"); + register_magic_helper(VM_RT_NEW_VECTOR_USING_VTABLE, + "org/apache/harmony/drlvm/gc_gen/GCHelper", "allocArray", + "(III)Lorg/vmmagic/unboxed/Address;"); +} + int gc_init() { INFO2("gc.process", "GC: call GC init...\n"); @@ -103,6 +115,8 @@ collector_initialize(gc); gc_init_heap_verification(gc); + + init_gc_helpers(); mutator_need_block = FALSE; Index: include/jit_runtime_support.h =================================================================== --- include/jit_runtime_support.h (revision 589494) +++ include/jit_runtime_support.h (working copy) @@ -19,6 +19,7 @@ #define _JIT_RUNTIME_SUPPORT_H_ #include "open/types.h" +#include "jni_types.h" /** * This is a complete set of functions used by the code generated by the JIT. @@ -775,6 +776,19 @@ */ VMEXPORT VM_RT_SUPPORT vm_helper_get_by_name(const char* name); +#ifndef Global_Env +struct Global_Env; +#endif + +jint helper_magic_init(Global_Env * vm_env); + +VMEXPORT jint register_magic_helper(VM_RT_SUPPORT id, + const char* class_name, + const char* method_name, + const char* method_descr); + +VMEXPORT Method_Handle get_magic_helper(VM_RT_SUPPORT id); + #ifdef __cplusplus } #endif // __cplusplus Index: vmcore/src/init/vm_init.cpp =================================================================== --- vmcore/src/init/vm_init.cpp (revision 589494) +++ vmcore/src/init/vm_init.cpp (working copy) @@ -40,6 +40,7 @@ #include "interpreter.h" #include "em_intf.h" #include "dll_jit_intf.h" +#include "jit_runtime_support.h" #include "jni_utils.h" #include "platform_lowlevel.h" #include "verify_stack_enumeration.h" @@ -829,6 +830,11 @@ // We assume, that at this point VM supports exception objects creation. vm_env->ReadyForExceptions(); + status = helper_magic_init(vm_env); + if(status != 0) { + return JNI_ERR; + } + return JNI_OK; } Index: vmcore/src/jit/rt_helper_info.cpp =================================================================== --- vmcore/src/jit/rt_helper_info.cpp (revision 589494) +++ vmcore/src/jit/rt_helper_info.cpp (working copy) @@ -18,6 +18,9 @@ #define LOG_DOMAIN "vm.helpers" #include "cxxlog.h" #include "jit_runtime_support.h" +#include "Class.h" +#include "environment.h" +#include "exceptions.h" #include #ifndef _WIN32 @@ -30,154 +33,231 @@ HELPER_INTERRUPTIBILITY_KIND i_kind; HELPER_CALLING_CONVENTION cc_kind; int number_of_args; + const char *magic_class_name; + const char *magic_method_name; + const char *magic_method_descr; + Method_Handle magic_mh; }; typedef std::map HelperInfoMap; static JIT_RT_Function_Entry _jit_rt_function_entries_base[] = { {VM_RT_NEW_RESOLVED_USING_VTABLE_AND_SIZE, "VM_RT_NEW_RESOLVED_USING_VTABLE_AND_SIZE", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_NEW_VECTOR_USING_VTABLE, "VM_RT_NEW_VECTOR_USING_VTABLE", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_MULTIANEWARRAY_RESOLVED, "VM_RT_MULTIANEWARRAY_RESOLVED", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_CDECL, 8}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_CDECL, 8, + NULL, NULL, NULL, NULL}, {VM_RT_LDC_STRING, "VM_RT_LDC_STRING", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_THROW, "VM_RT_THROW", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 1}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 1, + NULL, NULL, NULL, NULL}, {VM_RT_THROW_LAZY, "VM_RT_THROW_LAZY", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_DRL, 8}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_DRL, 8, + NULL, NULL, NULL, NULL}, {VM_RT_IDX_OUT_OF_BOUNDS, "VM_RT_IDX_OUT_OF_BOUNDS", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 0}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 0, + NULL, NULL, NULL, NULL}, {VM_RT_NULL_PTR_EXCEPTION, "VM_RT_NULL_PTR_EXCEPTION", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 0}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 0, + NULL, NULL, NULL, NULL}, {VM_RT_DIVIDE_BY_ZERO_EXCEPTION, "VM_RT_DIVIDE_BY_ZERO_EXCEPTION", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 0}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 0, + NULL, NULL, NULL, NULL}, {VM_RT_ARRAY_STORE_EXCEPTION, "VM_RT_ARRAY_STORE_EXCEPTION", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 0}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 0, + NULL, NULL, NULL, NULL}, {VM_RT_THROW_LINKING_EXCEPTION, "VM_RT_THROW_LINKING_EXCEPTION", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_DRL, 0}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_DRL, 0, + NULL, NULL, NULL, NULL}, {VM_RT_THROW_SET_STACK_TRACE, "VM_RT_THROW_SET_STACK_TRACE", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 1}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 1, + NULL, NULL, NULL, NULL}, {VM_RT_MONITOR_ENTER, "VM_RT_MONITOR_ENTER", - INTERRUPTIBLE_SOMETIMES, CALLING_CONVENTION_STDCALL, 1}, + INTERRUPTIBLE_SOMETIMES, CALLING_CONVENTION_STDCALL, 1, + "org/apache/harmony/drlvm/thread/ThreadHelper", "monitorEnterUseReservation", + "(Ljava/lang/Object;)V", NULL}, {VM_RT_MONITOR_ENTER_NON_NULL, "VM_RT_MONITOR_ENTER_NON_NULL", - INTERRUPTIBLE_SOMETIMES, CALLING_CONVENTION_STDCALL, 1}, + INTERRUPTIBLE_SOMETIMES, CALLING_CONVENTION_STDCALL, 1, + "org/apache/harmony/drlvm/thread/ThreadHelper", "monitorEnterUseReservation", + "(Ljava/lang/Object;)V", NULL}, {VM_RT_MONITOR_EXIT, "VM_RT_MONITOR_EXIT", - INTERRUPTIBLE_SOMETIMES, CALLING_CONVENTION_STDCALL, 1}, + INTERRUPTIBLE_SOMETIMES, CALLING_CONVENTION_STDCALL, 1, + "org/apache/harmony/drlvm/thread/ThreadHelper", "monitorExit", + "(Ljava/lang/Object;)V", NULL}, {VM_RT_MONITOR_EXIT_NON_NULL, "VM_RT_MONITOR_EXIT_NON_NULL", - INTERRUPTIBLE_SOMETIMES, CALLING_CONVENTION_STDCALL, 1}, + INTERRUPTIBLE_SOMETIMES, CALLING_CONVENTION_STDCALL, 1, + "org/apache/harmony/drlvm/thread/ThreadHelper", "monitorExit", + "(Ljava/lang/Object;)V", NULL}, {VM_RT_MONITOR_ENTER_STATIC, "VM_RT_MONITOR_ENTER_STATIC", - INTERRUPTIBLE_SOMETIMES, CALLING_CONVENTION_STDCALL, 1}, + INTERRUPTIBLE_SOMETIMES, CALLING_CONVENTION_STDCALL, 1, + "org/apache/harmony/drlvm/thread/ThreadHelper", "monitorEnterUseReservation", + "(Ljava/lang/Object;)V", NULL}, {VM_RT_MONITOR_EXIT_STATIC, "VM_RT_MONITOR_EXIT_STATIC", - INTERRUPTIBLE_SOMETIMES, CALLING_CONVENTION_STDCALL, 1}, + INTERRUPTIBLE_SOMETIMES, CALLING_CONVENTION_STDCALL, 1, + "org/apache/harmony/drlvm/thread/ThreadHelper", "monitorExit", + "(Ljava/lang/Object;)V", NULL}, {VM_RT_CHECKCAST, "VM_RT_CHECKCAST", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2, + "org/apache/harmony/drlvm/VMHelperFastPath", "checkCast", + "(Ljava/lang/Object;Lorg/vmmagic/unboxed/Address;ZZZI)Z", NULL}, {VM_RT_INSTANCEOF, "VM_RT_INSTANCEOF", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2, + "org/apache/harmony/drlvm/VMHelperFastPath", "instanceOf", + "(Ljava/lang/Object;Lorg/vmmagic/unboxed/Address;ZZZI)Z", NULL}, {VM_RT_AASTORE, "VM_RT_AASTORE", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 3}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 3, + NULL, NULL, NULL, NULL}, {VM_RT_AASTORE_TEST, "VM_RT_AASTORE_TEST", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_GET_INTERFACE_VTABLE_VER0, "VM_RT_GET_INTERFACE_VTABLE_VER0", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_INITIALIZE_CLASS, "VM_RT_INITIALIZE_CLASS", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 1}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 1, + NULL, NULL, NULL, NULL}, {VM_RT_GC_HEAP_WRITE_REF, "VM_RT_GC_HEAP_WRITE_REF", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_CDECL, 3}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_CDECL, 3, + NULL, NULL, NULL, NULL}, {VM_RT_GC_SAFE_POINT, "VM_RT_GC_SAFE_POINT", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 0}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 0, + NULL, NULL, NULL, NULL}, {VM_RT_GC_GET_TLS_BASE, "VM_RT_GET_TLS_BASE", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 0}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 0, + NULL, NULL, NULL, NULL}, {VM_RT_JVMTI_METHOD_ENTER_CALLBACK, "VM_RT_JVMTI_METHOD_ENTER_CALLBACK", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 1}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 1, + NULL, NULL, NULL, NULL}, {VM_RT_JVMTI_METHOD_EXIT_CALLBACK, "VM_RT_JVMTI_METHOD_EXIT_CALLBACK", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_JVMTI_FIELD_ACCESS_CALLBACK, "VM_RT_JVMTI_FIELD_ACCESS__CALLBACK", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 4}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 4, + NULL, NULL, NULL, NULL}, {VM_RT_JVMTI_FIELD_MODIFICATION_CALLBACK, "VM_RT_JVMTI_FIELD_MODIFICATION_CALLBACK", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 5}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 5, + NULL, NULL, NULL, NULL}, {VM_RT_NEWOBJ_WITHRESOLVE, "VM_RT_NEWOBJ_WITHRESOLVE", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_NEWARRAY_WITHRESOLVE, "VM_RT_NEWARRAY_WITHRESOLVE", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 3}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 3, + NULL, NULL, NULL, NULL}, {VM_RT_GET_NONSTATIC_FIELD_OFFSET_WITHRESOLVE, "VM_RT_GET_NONSTATIC_FIELD_OFFSET_WITHRESOLVE", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_GET_STATIC_FIELD_ADDR_WITHRESOLVE, "VM_RT_GET_STATIC_FIELD_ADDR_WITHRESOLVE", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_CHECKCAST_WITHRESOLVE, "VM_RT_CHECKCAST_WITHRESOLVE", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 3}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 3, + NULL, NULL, NULL, NULL}, {VM_RT_INSTANCEOF_WITHRESOLVE, "VM_RT_INSTANCEOF_WITHRESOLVE", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 3}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 3, + NULL, NULL, NULL, NULL}, {VM_RT_GET_INVOKESTATIC_ADDR_WITHRESOLVE, "VM_RT_GET_INVOKESTATIC_ADDR_WITHRESOLVE", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_GET_INVOKEINTERFACE_ADDR_WITHRESOLVE, "VM_RT_GET_INVOKEINTERFACE_ADDR_WITHRESOLVE", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 3}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 3, + NULL, NULL, NULL, NULL}, {VM_RT_GET_INVOKEVIRTUAL_ADDR_WITHRESOLVE, "VM_RT_GET_INVOKEVIRTUAL_ADDR_WITHRESOLVE", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 3}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 3, + NULL, NULL, NULL, NULL}, {VM_RT_GET_INVOKE_SPECIAL_ADDR_WITHRESOLVE, "VM_RT_GET_INVOKE_SPECIAL_ADDR_WITHRESOLVE", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_INITIALIZE_CLASS_WITHRESOLVE, "VM_RT_INITIALIZE_CLASS_WITHRESOLVE", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_F2I, "VM_RT_F2I", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 1}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 1, + NULL, NULL, NULL, NULL}, {VM_RT_F2L, "VM_RT_F2L", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 1}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 1, + NULL, NULL, NULL, NULL}, {VM_RT_D2I, "VM_RT_D2I", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 1}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 1, + NULL, NULL, NULL, NULL}, {VM_RT_D2L, "VM_RT_D2L", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 1}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 1, + NULL, NULL, NULL, NULL}, {VM_RT_LSHL, "VM_RT_LSHL", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_DRL, 2}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_DRL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_LSHR, "VM_RT_LSHR", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_DRL, 2}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_DRL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_LUSHR, "VM_RT_LUSHR", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_DRL, 2}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_DRL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_LMUL, "VM_RT_LMUL", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, #ifdef VM_LONG_OPT {VM_RT_LMUL_CONST_MULTIPLIER, "VM_RT_LMUL_CONST_MULTIPLIER", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, #endif // VM_LONG_OPT {VM_RT_LREM, "VM_RT_LREM", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_LDIV, "VM_RT_LDIV", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_ULDIV, "VM_RT_ULDIV", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_CONST_LDIV, "VM_RT_CONST_LDIV", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_CONST_LREM, "VM_RT_CONST_LREM", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_IMUL, "VM_RT_IMUL", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_IREM, "VM_RT_IREM", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_IDIV, "VM_RT_IDIV", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_FREM, "VM_RT_FREM", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_FDIV, "VM_RT_FDIV", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_DREM, "VM_RT_DREM", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_DDIV, "VM_RT_DDIV", - INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_NEVER, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, {VM_RT_CHAR_ARRAYCOPY_NO_EXC, "VM_RT_CHAR_ARRAYCOPY_NO_EXC", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 5}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 5, + NULL, NULL, NULL, NULL}, {VM_RT_WRITE_BARRIER_FASTCALL, "VM_RT_WRITE_BARRIER_FASTCALL", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2}, + INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 2, + NULL, NULL, NULL, NULL}, }; static JIT_RT_Function_Entry *jit_rt_function_entries = &(_jit_rt_function_entries_base[0]); @@ -257,3 +337,89 @@ return 0; } } + +Class* load_magic_helper_class(Global_Env * vm_env, const char * class_name) { + return vm_env->LoadCoreClass(class_name); +} + +void init_magic_helper_class(Class* magic_helper_class){ + tmn_suspend_disable(); + class_initialize(magic_helper_class); + + if(exn_raised()){ + DIE("Exception raised during " << magic_helper_class->get_name()->bytes << " class initializing."); + } + tmn_suspend_enable(); +} + +Method_Handle resolve_magic_helper(Global_Env * vm_env, + const char* class_name, + const char* method_name, + const char* method_descr) { + assert (class_name); + assert (method_name); + assert (method_descr); + + Class* magic_helper_class = load_magic_helper_class(vm_env, class_name); + init_magic_helper_class(magic_helper_class); + return class_lookup_method_recursive(magic_helper_class, method_name, method_descr); +} + +jint helper_magic_init(Global_Env * vm_env){ + for (int i = 0; i < num_jit_rt_function_entries; i++) { + const char* class_name = jit_rt_function_entries[i].magic_class_name; + const char* method_name = jit_rt_function_entries[i].magic_method_name; + const char* method_descr = jit_rt_function_entries[i].magic_method_descr; + + if (method_name == NULL){ + continue; + } + + assert (class_name); + assert (method_name); + assert (method_descr); + + Method_Handle method_handle = resolve_magic_helper(vm_env, class_name, method_name, method_descr); + jit_rt_function_entries[i].magic_mh = method_handle; + } + return JNI_OK; +} + +VMEXPORT +jint register_magic_helper(VM_RT_SUPPORT id, + const char* class_name, + const char* method_name, + const char* method_descr) { + assert (class_name); + assert (method_name); + assert (method_descr); + + HelperInfoMap::const_iterator it = helper_map->find(id); + if (helper_map->end() != it) { + assert(it->second); + if (it->second->magic_method_name) { + ASSERT(it->second->magic_method_name == NULL, "Helper " << id << " is registered already."); + return JNI_ERR; + } else { + it->second->magic_class_name = class_name; + it->second->magic_method_name = method_name; + it->second->magic_method_descr = method_descr; + return JNI_OK; + } + } else { + ASSERT(VM_RT_UNKNOWN == id, "Unexpected helper id " << id); + return JNI_ERR; + } +} + +VMEXPORT +Method_Handle get_magic_helper(VM_RT_SUPPORT id) { + HelperInfoMap::const_iterator it = helper_map->find(id); + if (helper_map->end() != it) { + assert(it->second); + return it->second->magic_mh; + } else { + ASSERT(false, "Unexpected helper id " << id); + return NULL; + } +}