示例#1
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;
}