in vm/vmcore/src/util/em64t/base/ini_em64t.cpp [199:387]
void JIT_execute_method_default(JIT_Handle jh, jmethodID methodID,
jvalue * result, jvalue * args) {
assert(!hythread_is_suspend_enabled());
ASSERT_RAISE_AREA;
static const invoke_managed_func_int_t invoke_managed_func =
(invoke_managed_func_int_t) gen_invoke_managed_func();
// holds arguments that should be placed in GR's
uint64 gr_args[MAX_GR];
// holds arguments that should be placed in FR's
double fr_args[MAX_FR];
// gen_invoke_managed_func assumes such size
assert(sizeof(double) == 8);
Method * const method = (Method *)methodID;
const void * const method_entry_point = method->get_code_addr();
Arg_List_Iterator iter = method->get_argument_list();
// hold arguments that should be placed on the memory stack
uint64 * const stack_args = (uint64 *) STD_MALLOC(sizeof(uint64) * method->get_num_args());
int64 gr_nargs = 0;
#ifdef _WIN64
# define fr_nargs gr_nargs
#else
int64 fr_nargs = 0;
#endif
int64 stack_nargs = 0;
int64 arg_num = 0;
TRACE2("invoke", "enter method "
<< method->get_class()->get_name()->bytes << " "
<< method->get_name()->bytes << " "
<< method->get_descriptor());
if(!method->is_static()) {
ObjectHandle handle = (ObjectHandle) args[arg_num++].l;
assert(handle);
// convert from native to managed NULL
gr_args[gr_nargs++] = (handle->object != NULL)
? (uint64) handle->object : (uint64) VM_Global_State::loader_env->managed_null;
}
Java_Type type;
while((type = curr_arg(iter)) != JAVA_TYPE_END) {
assert(gr_nargs <= MAX_GR);
assert(fr_nargs <= MAX_FR);
switch (type) {
case JAVA_TYPE_CLASS:
case JAVA_TYPE_ARRAY: {
ObjectHandle handle = (ObjectHandle) args[arg_num++].l;
uint64 ref = handle ? (uint64) handle->object : 0;
// convert from native to managed NULL
ref = ref ? ref : (uint64) VM_Global_State::loader_env->managed_null;
if (gr_nargs < MAX_GR) {
gr_args[gr_nargs++] = ref;
} else {
stack_args[stack_nargs++] = ref;
}
break;
}
case JAVA_TYPE_INT:
// sign extension
if (gr_nargs < MAX_GR) {
gr_args[gr_nargs++] = (int64) args[arg_num++].i;
} else {
stack_args[stack_nargs++] = (int64) args[arg_num++].i;
}
break;
case JAVA_TYPE_LONG:
// sign extension
if (gr_nargs < MAX_GR) {
gr_args[gr_nargs++] = (int64) args[arg_num++].j;
} else {
stack_args[stack_nargs++] = (int64) args[arg_num++].j;
}
break;
case JAVA_TYPE_SHORT:
// sign extension
if (gr_nargs < MAX_GR) {
gr_args[gr_nargs++] = (int64) args[arg_num++].s;
} else {
stack_args[stack_nargs++] = (int64) args[arg_num++].s;
}
break;
case JAVA_TYPE_CHAR:
// zero extension
if (gr_nargs < MAX_GR) {
gr_args[gr_nargs++] = (uint64) args[arg_num++].c;
} else {
stack_args[stack_nargs++] = (uint64) args[arg_num++].c;
}
break;
case JAVA_TYPE_BYTE:
// sign extension
if (gr_nargs < MAX_GR) {
gr_args[gr_nargs++] = (int64) args[arg_num++].b;
} else {
stack_args[stack_nargs++] = (int64) args[arg_num++].b;
}
break;
case JAVA_TYPE_BOOLEAN:
// sign extension
if (gr_nargs < MAX_GR) {
gr_args[gr_nargs++] = (int64) args[arg_num++].z;
} else {
stack_args[stack_nargs++] = (int64) args[arg_num++].z;
}
break;
case JAVA_TYPE_DOUBLE:
if (fr_nargs < MAX_FR) {
fr_args[fr_nargs++] = args[arg_num++].d;
} else {
*(double *)(stack_args + stack_nargs) = args[arg_num++].d;
++stack_nargs;
}
break;
case JAVA_TYPE_FLOAT:
if (fr_nargs < MAX_FR) {
*(float *)&fr_args[fr_nargs++] = args[arg_num++].f;
} else {
*(float *)(stack_args + stack_nargs) = args[arg_num++].f;
++stack_nargs;
}
break;
default:
LDIE(31, "INTERNAL ERROR: Unexpected type of the argument: {0}" << type);
}
iter = advance_arg_iterator(iter);
}
// Save the result
type = method->get_return_java_type();
switch(type) {
case JAVA_TYPE_VOID:
invoke_managed_func(FAKE_ARGUMENTS,
method_entry_point,
gr_nargs, fr_nargs, stack_nargs,
gr_args, fr_args, stack_args);
break;
case JAVA_TYPE_ARRAY:
case JAVA_TYPE_CLASS: {
ObjectHandle handle = NULL;
uint64 ref = invoke_managed_func(FAKE_ARGUMENTS,
method_entry_point,
gr_nargs, fr_nargs, stack_nargs,
gr_args, fr_args, stack_args);
// convert from managed to native NULL
ref = (ref != (uint64) VM_Global_State::loader_env->managed_null) ? ref : (uint64) NULL;
if (ref) {
handle = oh_allocate_local_handle();
handle->object = (ManagedObject*) ref;
}
result->l = handle;
break;
}
case JAVA_TYPE_LONG:
case JAVA_TYPE_INT:
case JAVA_TYPE_SHORT:
case JAVA_TYPE_CHAR:
case JAVA_TYPE_BYTE:
case JAVA_TYPE_BOOLEAN:
result->j = invoke_managed_func(FAKE_ARGUMENTS,
method_entry_point,
gr_nargs, fr_nargs, stack_nargs,
gr_args, fr_args, stack_args);
break;
case JAVA_TYPE_DOUBLE:
case JAVA_TYPE_FLOAT:
result->d = (invoke_managed_func_double_t(invoke_managed_func))(
FAKE_ARGUMENTS,
method_entry_point,
gr_nargs, fr_nargs, stack_nargs,
gr_args, fr_args, stack_args);
break;
default:
LDIE(32, "INTERNAL ERROR: Unexpected return type: {0}" << type);
}
STD_FREE(stack_args);
TRACE2("invoke", "exit method "
<< method->get_class()->get_name()->bytes << " "
<< method->get_name()->bytes << " "
<< method->get_descriptor());
}