Пример #1
0
// exception catch support for JVMTI, also restore stack after Stack Overflow Error
void jvmti_exception_catch_callback() {
    Registers regs = {0};
    VM_thread *thread = p_TLS_vmthread;
    assert(thread);

    if (thread->regs) {
        regs = *(Registers*)thread->regs;
    }

    M2nFrame* m2n = (M2nFrame *) STD_ALLOCA(m2n_get_size());
    m2n_push_suspended_frame(thread, m2n, &regs);
    M2nFrame* prev_m2n = m2n_get_previous_frame(m2n);

    StackIterator* si = (StackIterator*) STD_ALLOCA(si_size());
    si_fill_from_registers(si, &regs, false, prev_m2n);

    // si_create_from_registers uses large stack space,
    // so guard page restored after its invoke, 
    // but befor ti agent callback invokation, 
    // because it should work on protected page.
    if (p_TLS_vmthread->restore_guard_page) {
        int res = port_thread_restore_guard_page();

        if (res != 0) {
            Global_Env *env = VM_Global_State::loader_env;

            if (si_is_native(si)) {
                m2n_set_last_frame(prev_m2n);

                if ((interpreter_enabled() || (!prev_m2n) ||
                        (m2n_get_frame_type(prev_m2n) & FRAME_NON_UNWINDABLE))) {
                    exn_raise_by_class(env->java_lang_StackOverflowError_Class);
                } else {
                    //si_free(si);
                    exn_throw_by_class(env->java_lang_StackOverflowError_Class);
                }
            } else {
                //si_free(si);
                exn_throw_by_class(env->java_lang_StackOverflowError_Class);
            }
        }

        p_TLS_vmthread->restore_guard_page = false;
    }

    if (!si_is_native(si))
    {
        CodeChunkInfo* catch_cci = si_get_code_chunk_info(si);
        assert(catch_cci);
        Method* catch_method = catch_cci->get_method();
        NativeCodePtr catch_method_location = si_get_ip(si);
        JIT* catch_method_jit = catch_cci->get_jit();
        ManagedObject** exn_obj = (ManagedObject**) si_get_return_pointer(si);
        *exn_obj = jvmti_jit_exception_catch_event_callback_call( *exn_obj,
                catch_method_jit, catch_method, catch_method_location);
    }

    si_transfer_control(si);
}
Пример #2
0
/*
 * Get Bytecodes
 *
 * For the method indicated by method, return the byte codes that
 * implement the method. The number of bytecodes is returned via
 * bytecode_count_ptr. The byte codes themselves are returned via
 * bytecodes_ptr.
 *
 * OPTIONAL Functionality.
 */
jvmtiError JNICALL
jvmtiGetBytecodes(jvmtiEnv* env,
                  jmethodID method,
                  jint* bytecode_count_ptr,
                  unsigned char** bytecodes_ptr)
{
    TRACE("GetBytecodes called");
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase phases[] = {JVMTI_PHASE_START, JVMTI_PHASE_LIVE};

    CHECK_EVERYTHING();

    CHECK_CAPABILITY(can_get_bytecodes);

    /**
     * Check is_native_ptr
     */
    if( !bytecode_count_ptr || !bytecodes_ptr ) {
        return JVMTI_ERROR_NULL_POINTER;
    }
    /**
     * Check method
     */
    if( !method ) {
        return JVMTI_ERROR_INVALID_METHODID;
    }

    Method* mtd = (Method*)method;
    if( mtd->is_native() ) return JVMTI_ERROR_NATIVE_METHOD;
    if( mtd->get_byte_code_addr() == NULL ) return JVMTI_ERROR_OUT_OF_MEMORY;

    *bytecode_count_ptr = mtd->get_byte_code_size();
    jvmtiError err = _allocate( *bytecode_count_ptr, bytecodes_ptr );
    if( err != JVMTI_ERROR_NONE ) return err;
    memcpy( *bytecodes_ptr, mtd->get_byte_code_addr(), *bytecode_count_ptr );

    if (interpreter_enabled())
    {
        TIEnv *p_env = (TIEnv *)env;
        VMBreakPoints* vm_brpt = p_env->vm->vm_env->TI->vm_brpt;

        LMAutoUnlock lock(vm_brpt->get_lock());

        for (VMBreakPoint* bpt = vm_brpt->find_method_breakpoint(method); bpt;
             bpt = vm_brpt->find_next_method_breakpoint(bpt, method))
        {
            (*bytecodes_ptr)[bpt->location] =
                (unsigned char)bpt->saved_byte;
        }
    }

    return JVMTI_ERROR_NONE;
}
Пример #3
0
static void ti_enumerate_thread(TIEnv *ti_env, VM_thread* thread)
{
    TIIterationState *state = ti_env->iteration_state;
    state->root_kind = JVMTI_HEAP_ROOT_THREAD;
    state->thread_tag = ti_env->tags->get(
            (Managed_Object_Handle)
            jthread_self()->object);

    if (interpreter_enabled()) {
        interpreter.interpreter_ti_enumerate_thread((jvmtiEnv*)ti_env, thread);
    } else {
        jitted_ti_enumerate_thread((jvmtiEnv*)ti_env, thread);
    }
}
Пример #4
0
// exception catch callback to restore stack after Stack Overflow Error
void exception_catch_callback() {
    Registers regs = {0};
    VM_thread *thread = p_TLS_vmthread;
    assert(thread);

    if (thread->regs) {
        regs = *(Registers*)thread->regs;
    }

    M2nFrame* m2n = (M2nFrame *) STD_ALLOCA(m2n_get_size());
    m2n_push_suspended_frame(thread, m2n, &regs);
    M2nFrame* prev_m2n = m2n_get_previous_frame(m2n);

    StackIterator* si = (StackIterator*) STD_ALLOCA(si_size());
    si_fill_from_registers(si, &regs, false, prev_m2n);

    // si_create_from_registers uses large stack space,
    // so guard page restored after its invoke.
    if (p_TLS_vmthread->restore_guard_page) {
        int res = port_thread_restore_guard_page();

        if (res != 0) {
            Global_Env *env = VM_Global_State::loader_env;

            if (si_is_native(si)) {
                m2n_set_last_frame(prev_m2n);

                if ((interpreter_enabled() || (!prev_m2n) ||
                        (m2n_get_frame_type(prev_m2n) & FRAME_NON_UNWINDABLE))) {
                    exn_raise_by_class(env->java_lang_StackOverflowError_Class);
                } else {
                    //si_free(si);
                    exn_throw_by_class(env->java_lang_StackOverflowError_Class);
                }
            } else {
                //si_free(si);
                exn_throw_by_class(env->java_lang_StackOverflowError_Class);
            }
        }

        p_TLS_vmthread->restore_guard_page = false;
    }

    si_transfer_control(si);
}
Пример #5
0
IDATA jthread_throw_exception_object(jobject object)
{
    if (interpreter_enabled()) {
        // FIXME - Function set_current_thread_exception does the same
        // actions as exn_raise_object, and it should be replaced.
        hythread_suspend_disable();
        set_current_thread_exception(object->object);
        hythread_suspend_enable();
    } else {
        if (is_unwindable()) {
            exn_throw_object(object);
        } else {
            ASSERT_RAISE_AREA;
            exn_raise_object(object);
        }
    }

    return 0;
}
Пример #6
0
bool set_unwindable(bool unwindable)
{
    M2nFrame* lastFrame = m2n_get_last_frame();

    if (interpreter_enabled() || (!lastFrame)) {
        assert(!unwindable);
        return false;
    }

    int lastFrameType = m2n_get_frame_type(lastFrame);
    bool previousValue = !(lastFrameType & FRAME_NON_UNWINDABLE);

    if (unwindable) {
        lastFrameType &= ~FRAME_NON_UNWINDABLE;
    } else {
        lastFrameType |= FRAME_NON_UNWINDABLE;
    }
    m2n_set_frame_type( lastFrame, (frame_type) lastFrameType);
    return previousValue;
}
Пример #7
0
jvmtiError JNICALL
jvmtiGetLocalLong(jvmtiEnv* env,
                  jthread thread,
                  jint depth,
                  jint slot,
                  jlong* value_ptr)
{
    TRACE("GetLocalLong called");
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase phases[] = {JVMTI_PHASE_LIVE};

    CHECK_EVERYTHING();

    CHECK_CAPABILITY(can_access_local_variables);

    // check error condition: JVMTI_ERROR_INVALID_THREAD
    // check error condition: JVMTI_ERROR_THREAD_NOT_ALIVE
    // check error condition: JVMTI_ERROR_ILLEGAL_ARGUMENT
    // check error condition: JVMTI_ERROR_NULL_POINTER
    jvmtiError err = GetLocal_checkArgs(env, &thread, depth, slot, value_ptr);
    if (err != JVMTI_ERROR_NONE)
        return err;

    bool thread_suspended = false;
    // Suspend thread before getting stacks
    vm_thread_t vm_thread;
    if (NULL != thread)
    {
        // Check that this thread is not current
        vm_thread = jthread_get_vm_thread_ptr_safe(thread);
        if (vm_thread != p_TLS_vmthread)
        {
            IDATA UNREF status = hythread_suspend_other((hythread_t)vm_thread);
            assert(TM_ERROR_NONE == status);
            thread_suspended = true;
        }
    }
    else
        vm_thread = p_TLS_vmthread;

    if (interpreter_enabled())
        // check error condition: JVMTI_ERROR_INVALID_SLOT
        // check error condition: JVMTI_ERROR_OPAQUE_FRAME
        // check error condition: JVMTI_ERROR_NO_MORE_FRAMES
        // TODO: check error condition: JVMTI_ERROR_TYPE_MISMATCH
        err = interpreter.interpreter_ti_getLocal64(env,
            vm_thread, depth, slot, value_ptr);
    else
    {
        GET_JIT_FRAME_CONTEXT;

        tmn_suspend_disable();
        OpenExeJpdaError result = jit->get_local_var(method, jfc, slot,
            VM_DATA_TYPE_INT64, value_ptr);
        si_free(si);
        tmn_suspend_enable();

        err = jvmti_translate_jit_error(result);
    }

    if (thread_suspended)
        hythread_resume((hythread_t)vm_thread);

    return err;
}
Пример #8
0
/**
 * General function to set value of local variable.
 * @param var_type  type of the local variable
 * @param p_value   pointer to the new variable value
 */
static jvmtiError set_local(jvmtiEnv* env,
                            jthread thread,
                            jint depth,
                            jint slot,
                            VM_Data_Type var_type,
                            void* p_value)
{
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase phases[] = {JVMTI_PHASE_LIVE};

    CHECK_EVERYTHING();

    CHECK_CAPABILITY(can_access_local_variables);

    // check error condition: JVMTI_ERROR_INVALID_THREAD
    // check error condition: JVMTI_ERROR_THREAD_NOT_ALIVE
    // check error condition: JVMTI_ERROR_ILLEGAL_ARGUMENT
    jvmtiError err = GetLocal_checkArgs(env, &thread, depth, slot, p_value);
    if (err != JVMTI_ERROR_NONE)
        return err;

    // check error condition: JVMTI_ERROR_INVALID_OBJECT
    if (VM_DATA_TYPE_CLASS == var_type && ! is_valid_object(env, *(jobject*) p_value))
        return JVMTI_ERROR_INVALID_OBJECT;

    bool thread_suspended = false;
    // Suspend thread before getting stacks
    vm_thread_t vm_thread;
    if (NULL != thread)
    {
        // Check that this thread is not current
        vm_thread = jthread_get_vm_thread_ptr_safe(thread);
        if (vm_thread != p_TLS_vmthread)
        {
            IDATA UNREF status = hythread_suspend_other((hythread_t)vm_thread);
            assert(TM_ERROR_NONE == status);
            thread_suspended = true;
        }
    }
    else
        vm_thread = p_TLS_vmthread;

    if (interpreter_enabled())
    {
        // TODO: check error condition: JVMTI_ERROR_INVALID_SLOT
        // TODO: check error condition: JVMTI_ERROR_TYPE_MISMATCH
        // TODO: check error condition: JVMTI_ERROR_OPAQUE_FRAME
        // TODO: check error condition: JVMTI_ERROR_NO_MORE_FRAMES

        switch (var_type) {
            case VM_DATA_TYPE_CLASS:
                err = interpreter.interpreter_ti_setObject(env, vm_thread,
                        depth, slot, *(jobject*) p_value);
                break;
            case VM_DATA_TYPE_INT32:
            case VM_DATA_TYPE_F4:
                err = interpreter.interpreter_ti_setLocal32(env, vm_thread,
                        depth, slot, *(int*) p_value);
                break;
            case VM_DATA_TYPE_INT64:
            case VM_DATA_TYPE_F8:
                err = interpreter.interpreter_ti_setLocal64(env, vm_thread,
                        depth, slot, *(int64*) p_value);
                break;
            default:
                DIE(("Error: unrecognized local variable type"));
        }
    }
    else
    {
        GET_JIT_FRAME_CONTEXT;

        tmn_suspend_disable();
        OpenExeJpdaError result;

        switch (var_type) {
            case VM_DATA_TYPE_CLASS:
                if (NULL != *(jobject*) p_value)
                    result = jit->set_local_var(method, jfc, slot,
                        VM_DATA_TYPE_CLASS, &(*(ObjectHandle*) p_value)->object);
                else
                {
                    ManagedObject *n = (ManagedObject *)VM_Global_State::loader_env->managed_null;
                    result = jit->set_local_var(method, jfc, slot,
                        VM_DATA_TYPE_CLASS, &n);
                }

                break;
            case VM_DATA_TYPE_INT32:
            case VM_DATA_TYPE_F4:
            case VM_DATA_TYPE_INT64:
            case VM_DATA_TYPE_F8:
                result = jit->set_local_var(method, jfc, slot, var_type,
                        p_value);
                break;
            default:
                DIE(("Error: unrecognized local variable type"));
        }

        si_free(si);
        tmn_suspend_enable();

        err = jvmti_translate_jit_error(result);
    }

    if (thread_suspended)
        hythread_resume((hythread_t)vm_thread);

    return err;
}
Пример #9
0
bool is_unwindable()
{
    M2nFrame* lastFrame = m2n_get_last_frame();
    return !(interpreter_enabled() || (!lastFrame)
         || (m2n_get_frame_type(lastFrame) & FRAME_NON_UNWINDABLE));
}