Пример #1
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;
}