예제 #1
0
/*
 * Is Method Obsolete
 *
 * Has this method been made obsolete with RedefineClasses?
 *
 * REQUIRED Functionality.
 */
jvmtiError JNICALL
jvmtiIsMethodObsolete(jvmtiEnv* env,
                      jmethodID method,
                      jboolean* is_obsolete_ptr)
{
    TRACE("IsMethodObsolete called for " << method);
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase phases[] = {JVMTI_PHASE_START, JVMTI_PHASE_LIVE};

    CHECK_EVERYTHING();
    CHECK_CAPABILITY(can_redefine_classes);

    /**
     * Check is_obsolete_ptr
     */
    if( !is_obsolete_ptr ) {
        return JVMTI_ERROR_NULL_POINTER;
    }
    /**
     * Check method
     */
    if( !method ) {
        return JVMTI_ERROR_INVALID_METHODID;
    }
    /**
     * Since we don't have RedefineClasses yet, always return false
     */
    *is_obsolete_ptr = JNI_FALSE;

    TRACE("IsMethodObsolete(" << method << ") = " << *is_obsolete_ptr);
    return JVMTI_ERROR_NONE;
} // jvmtiIsMethodObsolete
예제 #2
0
/*
 * Get Current Thread CPU Time
 *
 * Return the CPU time utilized by the current thread.
 *
 * OPTIONAL Functionality.
 */
jvmtiError JNICALL
jvmtiGetCurrentThreadCpuTime(jvmtiEnv* env,
                             jlong* nanos_ptr)
{
    TRACE2("jvmti.timer", "GetCurrentThreadCpuTime called");
    IDATA status;
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase phases[] = {JVMTI_PHASE_START, JVMTI_PHASE_LIVE};
    CHECK_EVERYTHING();

    CHECK_CAPABILITY(can_get_current_thread_cpu_time);

    if (NULL == nanos_ptr)
        return JVMTI_ERROR_NULL_POINTER;

    status = jthread_get_thread_cpu_time(NULL, nanos_ptr);

    if (status != TM_ERROR_NONE)
        return JVMTI_ERROR_INTERNAL;

    return JVMTI_ERROR_NONE;
}
예제 #3
0
/*
 * Is Method Synthetic
 *
 * For the method indicated by method, return a value indicating
 * whether the method is synthetic via is_synthetic_ptr. Synthetic
 * methods are generated by the compiler but not present in the
 * original source code.
 *
 * OPTIONAL Functionality.
 */
jvmtiError JNICALL
jvmtiIsMethodSynthetic(jvmtiEnv* env,
                       jmethodID method,
                       jboolean* is_synthetic_ptr)
{
    TRACE("IsMethodSynthetic called");
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase phases[] = {JVMTI_PHASE_START, JVMTI_PHASE_LIVE};

    CHECK_EVERYTHING();
    CHECK_CAPABILITY(can_get_synthetic_attribute);

    /**
     * Check is_synthetic_ptr
     */
    if( !is_synthetic_ptr ) {
        return JVMTI_ERROR_NULL_POINTER;
    }
    /**
     * Check method
     */
    if( !method ) {
        return JVMTI_ERROR_INVALID_METHODID;
    }

    /**
     * Get method synthetic
     */
    *is_synthetic_ptr = (jboolean)(reinterpret_cast<Method*>(method)->is_synthetic() ? JNI_TRUE : JNI_FALSE);

    return JVMTI_ERROR_NONE;
} // jvmtiIsMethodSynthetic
예제 #4
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;
}
예제 #5
0
/*
 * Get Thread CPU Time
 *
 * Return the CPU time utilized by the specified thread.
 *
 * OPTIONAL Functionality.
 */
jvmtiError JNICALL
jvmtiGetThreadCpuTime(jvmtiEnv* env,
                      jthread thread,
                      jlong* nanos_ptr)
{
    TRACE2("jvmti.timer", "GetThreadCpuTime called");
    IDATA status;
    SuspendEnabledChecker sec;
   /*
     * Check given env & current phase.
     */
    jvmtiPhase phases[] = {JVMTI_PHASE_LIVE};

    CHECK_EVERYTHING();

    CHECK_CAPABILITY(can_get_thread_cpu_time);

    if (NULL == nanos_ptr)
        return JVMTI_ERROR_NULL_POINTER;

    if (NULL == thread) {
        status = jthread_get_thread_cpu_time(NULL, nanos_ptr);

    } else {
        if (! is_valid_thread_object(thread))
            return JVMTI_ERROR_INVALID_THREAD;

        // lock thread manager to avoid occasional change of thread state
        hythread_global_lock();

        int state;// =thread_get_thread_state(thread);
        jvmtiError err = jvmtiGetThreadState(env, thread, &state);
        if (err != JVMTI_ERROR_NONE){
   	    return err;
	    }

        switch (state)
        {
        case JVMTI_THREAD_STATE_TERMINATED:     // thread is terminated
        case JVMTI_JAVA_LANG_THREAD_STATE_NEW:  // thread is new
            hythread_global_unlock();
            return JVMTI_ERROR_THREAD_NOT_ALIVE;
        default:    // thread is alive
            status = jthread_get_thread_cpu_time(thread, nanos_ptr);

            break;
        }

        hythread_global_unlock();
    }

    if (status != TM_ERROR_NONE)
        return JVMTI_ERROR_INTERNAL;

    return JVMTI_ERROR_NONE;
}
예제 #6
0
/*
 * Get Thread CPU Timer Information
 *
 * Get information about the GetThreadCpuTime timer. The fields
 * of the jvmtiTimerInfo structure are filled in with details
 * about the timer.
 *
 * OPTIONAL Functionality.
 */
jvmtiError JNICALL
jvmtiGetThreadCpuTimerInfo(jvmtiEnv* env,
                           jvmtiTimerInfo* info_ptr)
{
    TRACE2("jvmti.timer", "GetThreadCpuTimerInfo called");
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase phases[] = {JVMTI_PHASE_LIVE};

    CHECK_EVERYTHING();

    CHECK_CAPABILITY(can_get_thread_cpu_time);

    if (NULL == info_ptr)
        return JVMTI_ERROR_NULL_POINTER;

    fill_timer_info(info_ptr);

    return JVMTI_ERROR_NONE;
}
예제 #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
/*
 * Get Local Variable Table
 *
 * Return local variable information.
 *
 * OPTIONAL Functionality.
 */
jvmtiError JNICALL
jvmtiGetLocalVariableTable(jvmtiEnv* env,
                           jmethodID method,
                           jint* entry_count_ptr,
                           jvmtiLocalVariableEntry** table_ptr)
{
    TRACE("GetLocalVariableTable called");
    SuspendEnabledChecker sec;
    int len,
        index,
        count;
    char *pointer;
    Method *method_ptr;
    jvmtiError result;

    /*
     * Check given env & current phase.
     */
    jvmtiPhase phases[] = {JVMTI_PHASE_LIVE};

    CHECK_EVERYTHING();

    CHECK_CAPABILITY(can_access_local_variables);

    /**
     * Check entry_count_ptr and table_ptr
     */
    if( !entry_count_ptr || !table_ptr ) {
        return JVMTI_ERROR_NULL_POINTER;
    }
    /**
     * Check method
     */
    if( !method ) {
        return JVMTI_ERROR_INVALID_METHODID;
    } else if( ((Method*)method)->is_native() ) {
        return JVMTI_ERROR_NATIVE_METHOD;
    }

    /**
     * Get method local variable table number entries
     */
    method_ptr = (Method*)method;
    count = method_ptr->get_local_var_table_size();
    if( count == 0 ) {
        return JVMTI_ERROR_ABSENT_INFORMATION;
    }

    /**
     * Allocate memory for local variable table
     */
    *entry_count_ptr = count;
    result = _allocate( count * sizeof(jvmtiLocalVariableEntry),
                        (unsigned char**)table_ptr );
    if( result != JVMTI_ERROR_NONE ) {
        return result;
    }

    /**
     * Set local variable table
     */
    for( index = 0; index < count; index++)
    {
        String *name, *type, *generic_type;
        jvmtiLocalVariableEntry* entry = *table_ptr + index;
        method_ptr->get_local_var_entry(index,
            &(entry->start_location),
            &(entry->length),
            &(entry->slot),
            &name, &type, &generic_type);
        // allocate memory for name
        len = get_utf8_length_of_8bit( (const U_8*)name->bytes, name->len);
        result = _allocate( len + 1, (unsigned char**)&pointer );
        if( result != JVMTI_ERROR_NONE ) {
            return result;
        }
        // copy variable name
        utf8_from_8bit( pointer, (const U_8*)name->bytes, name->len);
        // set variable name
        entry->name = pointer;
        // allocate memory for signature
        len = get_utf8_length_of_8bit( (const U_8*)type->bytes, type->len);
        result = _allocate( len + 1, (unsigned char**)&pointer );
        if( result != JVMTI_ERROR_NONE ) {
            return result;
        }
        // copy variable signature
        utf8_from_8bit( pointer, (const U_8*)type->bytes, type->len);
        // set variable signature
        entry->signature = pointer;
        // set variable slot

        if (generic_type) {
            // allocate memory for generic_signature
            len = get_utf8_length_of_8bit( (const U_8*)generic_type->bytes, generic_type->len);
            result = _allocate( len + 1, (unsigned char**)&pointer );
            if( result != JVMTI_ERROR_NONE ) {
                return result;
            }
            // copy variable generic_signature
            utf8_from_8bit( pointer, (const U_8*)generic_type->bytes, generic_type->len);
            // set variable generic_signature
            entry->generic_signature = pointer;
        } else {
            entry->generic_signature = NULL;
        }
    }

    return JVMTI_ERROR_NONE;
} // jvmtiGetLocalVariableTable
예제 #10
0
/*
 * Get Line Number Table
 *
 * For the method indicated by method, return a table of source
 * line number entries. The size of the table is returned via
 * entry_count_ptr and the table itself is returned via table_ptr.
 *
 * OPTIONAL Functionality.
 */
jvmtiError JNICALL
jvmtiGetLineNumberTable(jvmtiEnv* env,
                        jmethodID method,
                        jint* entry_count_ptr,
                        jvmtiLineNumberEntry** table_ptr)
{
    TRACE("GetLineNumberTable called");
    SuspendEnabledChecker sec;
    int index,
        count;
    Method *method_ptr;
    jvmtiError result;

    /*
     * Check given env & current phase.
     */
    jvmtiPhase phases[] = {JVMTI_PHASE_START, JVMTI_PHASE_LIVE};

    CHECK_EVERYTHING();

    CHECK_CAPABILITY(can_get_line_numbers);

    /**
     * Check entry_count_ptr and table_ptr
     */
    if( !entry_count_ptr || !table_ptr ) {
        return JVMTI_ERROR_NULL_POINTER;
    }
    /**
     * Check method
     */
    if( !method ) {
        return JVMTI_ERROR_INVALID_METHODID;
    } else if( ((Method*)method)->is_native() ) {
        return JVMTI_ERROR_NATIVE_METHOD;
    }

    /**
     * Get method line number table entries number
     */
    method_ptr = (Method*)method;
    count = method_ptr->get_line_number_table_size();
    if( count == 0 ) {
        return JVMTI_ERROR_ABSENT_INFORMATION;
    }

    /**
     * Allocate memory for line number table
     */
    *entry_count_ptr = count;
    result = _allocate( count * sizeof(jvmtiLineNumberEntry),
                        (unsigned char**)table_ptr );
    if( result != JVMTI_ERROR_NONE ) {
        return result;
    }

    /**
     * Set line number table
     */
    for( index = 0; index < count; ++index)
    {
        jvmtiLineNumberEntry* entry = *table_ptr + index;
        method_ptr->get_line_number_entry(index,
            &(entry->start_location),
            &(entry->line_number));
    }

    return JVMTI_ERROR_NONE;
} // jvmtiGetLineNumberTable