예제 #1
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;
}
예제 #2
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
예제 #3
0
/*
 * Get Method Location
 *
 * For the method indicated by method, return the beginning and
 * ending addresses through start_location_ptr and end_location_ptr.
 * In a conventional byte code indexing scheme, start_location_ptr
 * will always point to zero and end_location_ptr will always
 * point to the byte code count minus one.
 *
 * REQUIRED Functionality.
 */
jvmtiError JNICALL
jvmtiGetMethodLocation(jvmtiEnv* env,
                       jmethodID method,
                       jlocation* start_location_ptr,
                       jlocation* end_location_ptr)
{
    TRACE("GetMethodLocation called");
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase phases[] = {JVMTI_PHASE_START, JVMTI_PHASE_LIVE};

    CHECK_EVERYTHING();

    /**
     * Check start_location_ptr and end_location_ptr
     */
    if( !start_location_ptr || !end_location_ptr ) return JVMTI_ERROR_NULL_POINTER;

    /**
     * Check start_location_ptr and end_location_ptr
     */
    if( !method ) return JVMTI_ERROR_NULL_POINTER;

    *start_location_ptr = 0;
    *end_location_ptr = reinterpret_cast<Method*>(method)->get_byte_code_size()-1;
    return JVMTI_ERROR_NONE;
}
예제 #4
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
예제 #5
0
/*
 * Is Method Native
 *
 * For the method indicated by method, return a value indicating
 * whether the method is native via is_native_ptr
 *
 * REQUIRED Functionality.
 */
jvmtiError JNICALL
jvmtiIsMethodNative(jvmtiEnv* env,
                    jmethodID method,
                    jboolean* is_native_ptr)
{
    TRACE("IsMethodNative called for " << method);
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase phases[] = {JVMTI_PHASE_START, JVMTI_PHASE_LIVE};

    CHECK_EVERYTHING();

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

    *is_native_ptr = (jboolean)(reinterpret_cast<Method*>(method)->is_native()?JNI_TRUE:JNI_FALSE);
    TRACE("IsMethodNative(" << method << ") = " << *is_native_ptr);

    return JVMTI_ERROR_NONE;
}
예제 #6
0
/*
 * Get Method Declaring Class
 *
 * For the method indicated by method, return the class that
 * defined it via declaring_class_ptr.
 *
 * REQUIRED Functionality.
 */
jvmtiError JNICALL
jvmtiGetMethodDeclaringClass(jvmtiEnv* env,
                             jmethodID method,
                             jclass* declaring_class_ptr)
{
    TRACE("GetMethodDeclaringClass called for " << method);
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase phases[] = {JVMTI_PHASE_START, JVMTI_PHASE_LIVE};

    CHECK_EVERYTHING();

    if( !method ) return JVMTI_ERROR_INVALID_FIELDID;
    if( !declaring_class_ptr ) return JVMTI_ERROR_NULL_POINTER;

    Method* mtd = (Method*)method;
    Class* cls = mtd->get_class();

    ObjectHandle hclss = struct_Class_to_java_lang_Class_Handle(cls);
    ObjectHandle newH = NewLocalRef(p_TLS_vmthread->jni_env, hclss);

    *declaring_class_ptr = (jclass)newH;

    return JVMTI_ERROR_NONE;
}
예제 #7
0
/*
 * Get Method Modifiers
 *
 * For the method indicated by method, return the access flags
 * via modifiers_ptr.
 *
 * REQUIRED Functionality.
 */
jvmtiError JNICALL
jvmtiGetMethodModifiers(jvmtiEnv* env,
                        jmethodID method,
                        jint* modifiers_ptr)
{
    TRACE("GetMethodModifiers called");
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase phases[] = {JVMTI_PHASE_START, JVMTI_PHASE_LIVE};

    CHECK_EVERYTHING();

    if( !method ) return JVMTI_ERROR_NULL_POINTER;
    if( !modifiers_ptr ) return JVMTI_ERROR_NULL_POINTER;

    *modifiers_ptr = 0;
    Method* mtd = reinterpret_cast<Method*>(method);
    if( mtd->is_public() ) *modifiers_ptr |= ACC_PUBLIC;
    if( mtd->is_private() ) *modifiers_ptr |= ACC_PRIVATE;
    if( mtd->is_protected() ) *modifiers_ptr |= ACC_PROTECTED;
    if( mtd->is_static() ) *modifiers_ptr |= ACC_STATIC;
    if( mtd->is_final() ) *modifiers_ptr |= ACC_FINAL;
    if( mtd->is_synchronized() ) *modifiers_ptr |= ACC_SYNCHRONIZED;
    if( mtd->is_native() ) *modifiers_ptr |= ACC_NATIVE;
    if( mtd->is_abstract() ) *modifiers_ptr |= ACC_ABSTRACT;

    return JVMTI_ERROR_NONE;
}
예제 #8
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;
}
예제 #9
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;
}
예제 #10
0
/*
 * Get Method Name (and Signature)
 *
 * For the method indicated by method, return the method name via
 * name_ptr and method signature via signature_ptr.
 *
 * REQUIRED Functionality.
 */
jvmtiError JNICALL
jvmtiGetMethodName(jvmtiEnv* env,
                   jmethodID method,
                   char** name_ptr,
                   char** signature_ptr,
                   char** generic_ptr)
{
    TRACE("GetMethodName called");
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase phases[] = {JVMTI_PHASE_START, JVMTI_PHASE_LIVE};

    CHECK_EVERYTHING();

    if( !method ) return JVMTI_ERROR_NULL_POINTER;
    // Either name_ptr, signature_ptr, or generic_ptr can be NULL
    // In this case they are not returned

    char* mtd_name;
    char* mtd_sig;
    Method* mtd = reinterpret_cast<Method*>(method);
    jvmtiError err;
    if( name_ptr )
    {
        const String* name = mtd->get_name();
        err = _allocate(name->len + 1, (unsigned char**)(&mtd_name));
        if(err != JVMTI_ERROR_NONE)
            return err;
        // copy method name
        strcpy(mtd_name, name->bytes);
        *name_ptr = mtd_name;
    }

    if( signature_ptr )
    {
        const String* sig = mtd->get_descriptor();
        err = _allocate(sig->len + 1, (unsigned char**)(&mtd_sig));
        if(err != JVMTI_ERROR_NONE)
        {
            if(name_ptr && mtd_name)
                _deallocate((unsigned char*)mtd_name);
            return err;
        }
        // copy method signature
        strcpy(mtd_sig, sig->bytes);
        *signature_ptr = mtd_sig;
    }

    // ppervov: no generics support in VM as of yet
    if( generic_ptr )
        *generic_ptr = NULL;

    return JVMTI_ERROR_NONE;
}
예제 #11
0
/*
 * Dispose Environment
 *
 * Shutdown a JVMTI connection created with JNI GetEnv (see JVMTI
 * Environments). Dispose of any resources held by the environment.
 * Suspended threads are not resumed, this must be done explicitly
 * by the agent. Allocated memory is not released, this must be
 * done explicitly by the agent. This environment may not be used
 * after this call. This call returns to the caller.
 *
 * REQUIRED Functionality.
 */
jvmtiError JNICALL
jvmtiDisposeEnvironment(jvmtiEnv* env)
{
    TRACE2("jvmti.general", "DisposeEnvironment called, env = " << env);
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase* phases = NULL;

    CHECK_EVERYTHING();

    TIEnv *p_env = (TIEnv *)env;
    DebugUtilsTI *ti = p_env->vm->vm_env->TI;
    LMAutoUnlock lock(&ti->TIenvs_lock);

    // Disable all global events for this environment
    int iii;
    for (iii = JVMTI_MIN_EVENT_TYPE_VAL; iii <= JVMTI_MAX_EVENT_TYPE_VAL; iii++)
        remove_event_from_global(env, (jvmtiEvent)iii);

    // Disable all thread local events for this environment, do it only in live phase
    // otherwise environment couldn't register for any thread local events
    // because it couldn't get any live thread references
    jvmtiPhase ph;
    jvmtiGetPhase(env, &ph);
    if (JVMTI_PHASE_LIVE == ph)
    {
        // FIXME: this loop is very ugly, could we improve it?
        jint threads_number;
        jthread *threads;
        jvmtiGetAllThreads(env, &threads_number, &threads);
        for (int jjj = 0; jjj < threads_number; jjj++)
            for (iii = JVMTI_MIN_EVENT_TYPE_VAL; iii <= JVMTI_MAX_EVENT_TYPE_VAL; iii++)
                remove_event_from_thread(env, (jvmtiEvent)iii, threads[jjj]);
        _deallocate((unsigned char *)threads);
    }

    // Remove all breakpoints set by this environment and release interface
    ti->vm_brpt->release_intf(p_env->brpt_intf);

    // Remove all capabilities for this environment
    jvmtiRelinquishCapabilities(env, &p_env->posessed_capabilities);

    // Remove environment from the global list
    p_env->vm->vm_env->TI->removeEnvironment(p_env);

    _deallocate((unsigned char *)env);

    return JVMTI_ERROR_NONE;
}
예제 #12
0
/*
 * Set Environment Local Storage
 *
 * The VM stores a pointer value associated with each environment.
 * This pointer value is called environment-local storage. This
 * value is NULL unless set with this function.
 *
 * REQUIRED Functionality.
 */
jvmtiError JNICALL
jvmtiSetEnvironmentLocalStorage(jvmtiEnv* env,
                                const void* data)
{
    TRACE("SetEnvironmentLocalStorage called, data = " << data);
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase* phases = NULL;

    CHECK_EVERYTHING();

    ((TIEnv *)env)->user_storage = const_cast<void*>(data);

    return JVMTI_ERROR_NONE;
}
예제 #13
0
/*
 * Get Phase
 *
 * Return the current phase of VM execution.
 *
 * REQUIRED Functionality.
 */
jvmtiError JNICALL
jvmtiGetPhase(jvmtiEnv* env,
              jvmtiPhase* phase_ptr)
{
    TRACE2("jvmti.general", "GetPhase called");
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase* phases = NULL;

    CHECK_EVERYTHING();

    if (NULL == phase_ptr)
        return JVMTI_ERROR_NULL_POINTER;

    *phase_ptr = ((TIEnv *)env)->vm->vm_env->TI->getPhase();
    TRACE2("jvmti", "Phase = " << *phase_ptr);
    return JVMTI_ERROR_NONE;
}
예제 #14
0
/*
 * Get Timer Information
 *
 * Get information about the GetTime timer. The fields of the
 * jvmtiTimerInfo structure are filled in with details about the
 * timer. This information will not change during a particular
 * invocation of the VM.
 *
 * REQUIRED Functionality.
 */
jvmtiError JNICALL
jvmtiGetTimerInfo(jvmtiEnv* env,
                  jvmtiTimerInfo* info_ptr)
{
    TRACE2("jvmti.timer", "GetTimerInfo called");
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase* phases = NULL;

    CHECK_EVERYTHING();

    if (NULL == info_ptr)
        return JVMTI_ERROR_NULL_POINTER;

    fill_timer_info(info_ptr);

    return JVMTI_ERROR_NONE;
}
예제 #15
0
/*
 * Get Environment Local Storage
 *
 * Called by the agent to get the value of the JVMTI
 * environment-local storage
 *
 * REQUIRED Functionality.
 */
jvmtiError JNICALL
jvmtiGetEnvironmentLocalStorage(jvmtiEnv* env,
                                void** data_ptr)
{
    TRACE2("jvmti.general", "GetEnvironmentLocalStorage called");
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase* phases = NULL;

    CHECK_EVERYTHING();

    if (NULL == data_ptr)
        return JVMTI_ERROR_NULL_POINTER;

    *data_ptr = ((TIEnv *)env)->user_storage;

    return JVMTI_ERROR_NONE;
}
예제 #16
0
/*
 * Get Version Number
 *
 * Return the JVMTI version via version_ptr. The return value is
 * the version identifier. The version identifier includes major,
 * minor and micro version as well as the interface type.
 *
 * REQUIRED Functionality.
 */
jvmtiError JNICALL
jvmtiGetVersionNumber(jvmtiEnv* env,
                      jint* version_ptr)
{
    TRACE2("jvmti.general", "GetVersionNumber called");
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase* phases = NULL;

    CHECK_EVERYTHING();

    if (NULL == version_ptr)
        return JVMTI_ERROR_NULL_POINTER;

    *version_ptr = JVMTI_VERSION;

    return JVMTI_ERROR_NONE;
}
예제 #17
0
/*
 * Get Arguments Size
 *
 * For the method indicated by method, return via max_ptr the
 * number of local variable slots used by the method's arguments.
 * Note that two-word arguments use two slots
 *
 * REQUIRED Functionality.
 */
jvmtiError JNICALL
jvmtiGetArgumentsSize(jvmtiEnv* env,
                      jmethodID method,
                      jint* size_ptr)
{
    TRACE("GetArgumentsSize called");
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase phases[] = {JVMTI_PHASE_START, JVMTI_PHASE_LIVE};

    CHECK_EVERYTHING();

    if( !method ) return JVMTI_ERROR_NULL_POINTER;
    if( !size_ptr ) return JVMTI_ERROR_NULL_POINTER;

    *size_ptr = reinterpret_cast<Method*>(method)->get_num_arg_slots();

    return JVMTI_ERROR_NONE;
}
예제 #18
0
/*
 * Get Available Processors
 *
 * Returns the number of processors available to the Java virtual
 * machine.
 *
 * REQUIRED Functionality.
 */
jvmtiError JNICALL
jvmtiGetAvailableProcessors(jvmtiEnv* env,
                            jint* processor_count_ptr)
{
    TRACE2("jvmti.timer", "GetAvailableProcessors called");
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase* phases = NULL;

    CHECK_EVERYTHING();

    if (processor_count_ptr == NULL)
    {
        return JVMTI_ERROR_NULL_POINTER;
    }

    *processor_count_ptr = port_CPUs_number();

    return JVMTI_ERROR_NONE;
}
예제 #19
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;
}
예제 #20
0
/*
 * Get Time
 *
 * Return the current value of the system timer, in nanoseconds.
 *
 * REQUIRED Functionality.
 */
jvmtiError JNICALL
jvmtiGetTime(jvmtiEnv* env,
             jlong* nanos_ptr)
{
    TRACE2("jvmti.timer", "GetTime called");
    SuspendEnabledChecker sec;
    /*
     * Check given env & current phase.
     */
    jvmtiPhase* phases = NULL;

    CHECK_EVERYTHING();

    if (nanos_ptr == NULL)
    {
        return JVMTI_ERROR_NULL_POINTER;
    }
    // get time in milliseconds
    apr_time_t apr_time = apr_time_now();

    *nanos_ptr = ((jlong) apr_time) * 1000ULL; // convert to nanos

    return JVMTI_ERROR_NONE;
}
예제 #21
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;
}
예제 #22
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;
}
예제 #23
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
예제 #24
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