void JIT_execute_method_default()

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());
}