示例#1
0
文件: compile.cpp 项目: dacut/juliet
VMEXPORT void vm_compiled_method_load(Method_Handle method, U_32 codeSize, 
                                  void* codeAddr, U_32 mapLength, 
                                  AddrLocation* addrLocationMap, 
                                  void* compileInfo, Method_Handle outer_method) 
{
    assert(method);
    assert(outer_method);

    outer_method->add_inline_info_entry(method, codeSize, codeAddr, mapLength,
            addrLocationMap);

    // Find TI environment
    DebugUtilsTI *ti = VM_Global_State::loader_env->TI;

    // Call TI callbacks
    if (jvmti_should_report_event(JVMTI_EVENT_COMPILED_METHOD_LOAD)
        && ti->getPhase() == JVMTI_PHASE_LIVE)
    {
        jvmti_send_region_compiled_method_load_event(method, codeSize,
            codeAddr, mapLength, addrLocationMap, NULL);
    }
}
示例#2
0
/**
 * Detaches current thread from VM.
 */
jint vm_detach(jobject java_thread)
{
    assert(hythread_is_suspend_enabled());

    hythread_t native_thread = jthread_get_native_thread(java_thread);
    assert(native_thread);
    vm_thread_t p_vm_thread = jthread_get_vm_thread(native_thread);
    assert(p_vm_thread);

    // Send Thread End event
    if(jvmti_should_report_event(JVMTI_EVENT_THREAD_END)) {
        jvmti_send_thread_start_end_event(p_vm_thread, 0);
    }

    // change java_status for native thread
    native_thread->java_status = TM_STATUS_ALLOCATED;

    if (native_thread == hythread_self()) {
        // Notify GC about thread detaching.
        // FIXME - GC notify detach thread works for current thread only
        gc_thread_kill(&p_vm_thread->_gc_private_information);
    }

    if (ti_is_enabled())
    {
        apr_status_t UNREF status;
        status = port_vmem_free(
            p_vm_thread->jvmti_thread.jvmti_jit_breakpoints_handling_buffer,
            TM_JVMTI_MAX_BUFFER_SIZE);
        assert(status == APR_SUCCESS);
    }

    // Destroy current VM_thread pool and zero VM_thread structure
    jthread_deallocate_vm_thread_pool(p_vm_thread);

    return JNI_OK;
}
示例#3
0
文件: compile.cpp 项目: dacut/juliet
JIT_Result compile_do_compilation_jit(Method* method, JIT* jit)
{
    // Time stamp for counting the total compilation time
    apr_time_t start;

    Global_Env * vm_env = VM_Global_State::loader_env;

    assert(method);
    assert(jit);

    if (!parallel_jit) {
        vm_env->p_jit_a_method_lock->_lock();
        // MikhailF reports that each JIT in recompilation chain has its own
        // JIT* pointer.
        // If in addition to recompilation chains one adds recompilation loops,
        // this check can be skipped, or main_code_chunk_id should be
        // modified.

        if (NULL != method->get_chunk_info_no_create_mt(jit, CodeChunkInfo::main_code_chunk_id)) {
            vm_env->p_jit_a_method_lock->_unlock();
            return JIT_SUCCESS;
        }
    }

    OpenMethodExecutionParams flags = {0}; 
    jvmti_get_compilation_flags(&flags);
    flags.exe_insert_write_barriers = gc_requires_barriers();

    Compilation_Handle ch;
    ch.env = VM_Global_State::loader_env;
    ch.jit = jit;

    start = apr_time_now();

    TRACE("compile_do_compilation_jit(): calling jit->compile_method_with_params() for method " << method );

    JIT_Result res = jit->compile_method_with_params(&ch, method, flags);

    TRACE("compile_do_compilation_jit(): returned from jit->compile_method_with_params() for method " << method );

    UNSAFE_REGION_START
    // Non-atomic increment of statistic counter
    // Conversion from microseconds to milliseconds
    vm_env->total_compilation_time += ((apr_time_now() - start)/1000);
    UNSAFE_REGION_END

    if (JIT_SUCCESS != res) {
        if (!parallel_jit) {
            vm_env->p_jit_a_method_lock->_unlock();
        }
        return res;
    }

    method->lock();
    for (CodeChunkInfo* cci = method->get_first_JIT_specific_info();  cci;  cci = cci->_next) {
        if (cci->get_jit() == jit) {
            compile_flush_generated_code_block((U_8*)cci->get_code_block_addr(), cci->get_code_block_size());
            // We assume the main chunk starts from entry point
            if (cci->get_id() == CodeChunkInfo::main_code_chunk_id) {
                method->set_code_addr(cci->get_code_block_addr());
            }
        }
    }

    // Commit the compilation by setting the method's code address
    method->set_state(Method::ST_Compiled);
    method->do_jit_recompiled_method_callbacks();
    method->apply_vtable_patches();
    method->unlock();
    if (!parallel_jit) {
        vm_env->p_jit_a_method_lock->_unlock();
    }

    // Find TI environment
    DebugUtilsTI *ti = vm_env->TI;

    // Call TI callbacks
    if (jvmti_should_report_event(JVMTI_EVENT_COMPILED_METHOD_LOAD)
        && ti->getPhase() == JVMTI_PHASE_LIVE)
    {
        jvmti_send_chunks_compiled_method_load_event(method);
    }
    return JIT_SUCCESS;
}
示例#4
0
/**
 * Gains the ownership over monitor.
 *
 * Current thread blocks if the specified monitor is owned by other thread.
 *
 * @param[in] monitor object where monitor is located
 * @sa JNI::MonitorEnter()
 */
IDATA VMCALL jthread_monitor_enter(jobject monitor)
{
    IDATA state;
    hythread_t native_thread;
    apr_time_t enter_begin;

    assert(monitor);
    hythread_suspend_disable();
    hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor);
    IDATA status = hythread_thin_monitor_try_enter(lockword);
    if (status != TM_ERROR_EBUSY) {
        goto entered;
    }

#ifdef LOCK_RESERVATION
    // busy unreserve lock before blocking and inflating
    while (TM_ERROR_NONE != hythread_unreserve_lock(lockword)) {
        hythread_yield();
        hythread_safe_point();
        hythread_exception_safe_point();
        lockword = vm_object_get_lockword_addr(monitor);
    }
    status = hythread_thin_monitor_try_enter(lockword);
    if (status != TM_ERROR_EBUSY) {
        goto entered;
    }
#endif //LOCK_RESERVATION

    native_thread = hythread_self();
    hythread_thread_lock(native_thread);
    state = hythread_get_state(native_thread);
    state &= ~TM_THREAD_STATE_RUNNABLE;
    state |= TM_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
    status = hythread_set_state(native_thread, state);
    assert(status == TM_ERROR_NONE);
    hythread_thread_unlock(native_thread);

    // should be moved to event handler
    if (ti_is_enabled()) {
        enter_begin = apr_time_now();
        int disable_count = hythread_reset_suspend_disable();
        jthread_set_owned_monitor(monitor);
        if(jvmti_should_report_event(JVMTI_EVENT_MONITOR_CONTENDED_ENTER)) {
            jvmti_send_contended_enter_or_entered_monitor_event(monitor, 1);
        }
        hythread_set_suspend_disable(disable_count);
    }

    // busy wait and inflate
    // reload pointer after safepoints
    lockword = vm_object_get_lockword_addr(monitor);
    while ((status =
            hythread_thin_monitor_try_enter(lockword)) == TM_ERROR_EBUSY)
    {
        hythread_safe_point();
        hythread_exception_safe_point();
        lockword = vm_object_get_lockword_addr(monitor);

        if (hythread_is_fat_lock(*lockword)) {
            status = hythread_thin_monitor_enter(lockword);
            if (status != TM_ERROR_NONE) {
                hythread_suspend_enable();
                assert(0);
                return status;
            }
            goto contended_entered;
        }
        hythread_yield();
    }
    assert(status == TM_ERROR_NONE);
    if (!hythread_is_fat_lock(*lockword)) {
        hythread_inflate_lock(lockword);
    }

// do all ti staff here
contended_entered:
    if (ti_is_enabled()) {
        int disable_count = hythread_reset_suspend_disable();
        if(jvmti_should_report_event(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED)) {
            jvmti_send_contended_enter_or_entered_monitor_event(monitor, 0);
        }
        hythread_set_suspend_disable(disable_count);
        // should be moved to event handler
        jvmti_thread_t jvmti_thread =
            jthread_get_jvmti_thread(hythread_self());
        jvmti_thread->blocked_time += apr_time_now() - enter_begin;
    }

    hythread_thread_lock(native_thread);
    state = hythread_get_state(native_thread);
    state &= ~TM_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
    state |= TM_THREAD_STATE_RUNNABLE;
    status = hythread_set_state(native_thread, state);
    assert(status == TM_ERROR_NONE);
    hythread_thread_unlock(native_thread);

entered:
    if (ti_is_enabled()) {
        jthread_add_owned_monitor(monitor);
    }
    hythread_suspend_enable();
    return TM_ERROR_NONE;
} // jthread_monitor_enter
示例#5
0
/**
 * Wait on the <code>object</code>'s monitor with the specified timeout.
 *
 * This function instructs the current thread to be scheduled off 
 * the processor and wait on the monitor until the following occurs: 
 * <UL>
 * <LI>another thread invokes <code>thread_notify(object)</code>
 * and VM chooses this thread to wake up;
 * <LI>another thread invokes <code>thread_notifyAll(object);</code>
 * <LI>another thread invokes <code>thread_interrupt(thread);</code>
 * <LI>real time elapsed from the waiting begin is
 * greater or equal the timeout specified.
 * </UL>
 *
 * @param[in] monitor object where monitor is located
 * @param[in] millis time to wait (in milliseconds)
 * @param[in] nanos time to wait (in nanoseconds)
 * @sa java.lang.Object.wait()
 */
IDATA VMCALL
jthread_monitor_timed_wait(jobject monitor, jlong millis, jint nanos)
{
    assert(monitor);

    hythread_suspend_disable();
    hythread_t native_thread = hythread_self();
    hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor);
    if (!hythread_is_fat_lock(*lockword)) {
        if (!hythread_owns_thin_lock(native_thread, *lockword)) {
            CTRACE(("ILLEGAL_STATE wait %x\n", lockword));
            hythread_suspend_enable();
            return TM_ERROR_ILLEGAL_STATE;
        }
        hythread_inflate_lock(lockword);
    }

    apr_time_t wait_begin;
    if (ti_is_enabled()) {
        int disable_count = hythread_reset_suspend_disable();
        jthread_set_wait_monitor(monitor);
        jthread_set_owned_monitor(monitor);
        if(jvmti_should_report_event(JVMTI_EVENT_MONITOR_WAIT)) {
            jvmti_send_wait_monitor_event(monitor, (jlong) millis);
        }
        if(jvmti_should_report_event(JVMTI_EVENT_MONITOR_CONTENDED_ENTER)) {
            jvmti_send_contended_enter_or_entered_monitor_event(monitor, 1);
        }
        hythread_set_suspend_disable(disable_count);

        // should be moved to event handler
        wait_begin = apr_time_now();
        jthread_remove_owned_monitor(monitor);
    }

    hythread_thread_lock(native_thread);
    IDATA state = hythread_get_state(native_thread);
    state &= ~TM_THREAD_STATE_RUNNABLE;
    state |= TM_THREAD_STATE_WAITING | TM_THREAD_STATE_IN_MONITOR_WAIT;
    if ((millis > 0) || (nanos > 0)) {
        state |= TM_THREAD_STATE_WAITING_WITH_TIMEOUT;
    }
    else {
        state |= TM_THREAD_STATE_WAITING_INDEFINITELY;
    }
    IDATA status = hythread_set_state(native_thread, state);
    assert(status == TM_ERROR_NONE);
    hythread_thread_unlock(native_thread);

    status =
        hythread_thin_monitor_wait_interruptable(lockword, millis, nanos);

    hythread_thread_lock(native_thread);
    state = hythread_get_state(native_thread);
    if ((millis > 0) || (nanos > 0)) {
        state &= ~TM_THREAD_STATE_WAITING_WITH_TIMEOUT;
    }
    else {
        state &= ~TM_THREAD_STATE_WAITING_INDEFINITELY;
    }
    state &= ~(TM_THREAD_STATE_WAITING | TM_THREAD_STATE_IN_MONITOR_WAIT);
    state |= TM_THREAD_STATE_RUNNABLE;
    hythread_set_state(native_thread, state);
    hythread_thread_unlock(native_thread);

    hythread_suspend_enable();
    if (ti_is_enabled()) {
        jthread_add_owned_monitor(monitor);
        int disable_count = hythread_reset_suspend_disable();
        if(jvmti_should_report_event(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED)) {
            jvmti_send_contended_enter_or_entered_monitor_event(monitor, 0);
        }
        if(jvmti_should_report_event(JVMTI_EVENT_MONITOR_WAITED)) {
            jvmti_send_waited_monitor_event(monitor,
                ((status == APR_TIMEUP) ? (jboolean) 1 : (jboolean) 0));
        }
        hythread_set_suspend_disable(disable_count);
        // should be moved to event handler
        jvmti_thread_t jvmti_thread =
            jthread_get_jvmti_thread(hythread_self());
        jvmti_thread->waited_time += apr_time_now() - wait_begin;
    }
    return status;
} // jthread_monitor_timed_wait