示例#1
0
// Note: Function runs from unwindable area before exception throwing
// function can be safe point & should be called with disable recursion = 1
static ManagedObject *create_lazy_exception(
    Class_Handle exn_class,
    Method_Handle exn_constr,
    U_8 * exn_constr_args,
    jvalue* vm_exn_constr_args)
{
    assert(!hythread_is_suspend_enabled());

    bool unwindable = set_unwindable(false);
    ManagedObject* result;
    if (NULL == vm_exn_constr_args) {
        result = class_alloc_new_object_and_run_constructor(
            (Class*) exn_class, (Method*) exn_constr, exn_constr_args);
    } else {
        // exception is throwing, so suspend can be enabled safely
        tmn_suspend_enable();
        jthrowable exc_object = create_exception(
            (Class*) exn_class, (Method*) exn_constr, vm_exn_constr_args);

        if (exc_object) {
            result = exc_object->object;
        } else {
            result = NULL;
        }
        tmn_suspend_disable();
    }
    set_unwindable(unwindable);
    exn_rethrow_if_pending();
    return result;
}   //create_object_lazily
void exn_throw_by_class_internal(Class* exc_class, const char* exc_message,
    jthrowable exc_cause)
{
    BEGIN_RAISE_AREA;
    // functions can be invoked in suspend disabled and enabled state
    if (!hythread_is_suspend_enabled()) {
        // exception is throwing, so suspend can be enabled safely
        tmn_suspend_enable();
    }
    assert(hythread_is_suspend_enabled());
#ifdef VM_LAZY_EXCEPTION
    //set_unwindable(false);

    jvalue args[3];
    Method* exc_init = prepare_exc_creating(
            exc_class, args, exc_message, exc_cause);

    if (NULL == exc_init) {
        CTRACE(("%s",
            "exn_throw_by_class(),create exception and delegating to exn_throw_for_JIT()"));
        jthrowable exc_object = exn_create(exc_class, exc_message, exc_cause);
        exn_rethrow_if_pending();
        //set_unwindable(true);
        exn_throw_object_internal(exc_object);
    } else {
        CTRACE(("%s", "exn_throw_by_class(), lazy delegating to exn_throw_for_JIT()"));
        //set_unwindable(true);

        // no return, so enable isn't required
        tmn_suspend_disable();
        exn_throw_for_JIT(NULL, exc_class, exc_init, NULL, args);
        //tmn_suspend_enable();
    }
#else
    jthrowable exc_object = exn_create(exc_class, exc_message, exc_cause);
    exn_rethrow_if_pending();
    exn_throw_object_internal(exc_object);
#endif
    END_RAISE_AREA;
}