U_32 si_get_inline_depth(StackIterator* si) { // // Here we assume that JIT data blocks can store only InlineInfo // A better idea is to extend JIT_Data_Block with some type information // Example: // // enum JIT_Data_Block_Type { InlineInfo, Empty } // // struct JIT_Data_Block { // JIT_Data_Block *next; // JIT_Data_Block_Type type; // char bytes[1]; // }; // // void *Method::allocate_JIT_data_block(size_t size, JIT *jit, JIT_Data_Block_Type) // ASSERT_NO_INTERPRETER CodeChunkInfo* cci = si_get_code_chunk_info(si); if ( cci != NULL && cci->has_inline_info()) { return cci->get_jit()->get_inline_depth( cci->get_inline_info(), // FIXME64: no support for large methods (U_32)((POINTER_SIZE_INT)si_get_ip(si) - (POINTER_SIZE_INT)cci->get_code_block_addr())); } return 0; }
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; }