< prev index next >

src/share/vm/interpreter/templateInterpreter.cpp

Print this page

        

*** 28,37 **** --- 28,38 ---- #include "interpreter/interpreterRuntime.hpp" #include "interpreter/interp_masm.hpp" #include "interpreter/templateInterpreter.hpp" #include "interpreter/templateInterpreterGenerator.hpp" #include "interpreter/templateTable.hpp" + #include "memory/resourceArea.hpp" #ifndef CC_INTERP # define __ _masm->
*** 217,596 **** DispatchTable TemplateInterpreter::_active_table; DispatchTable TemplateInterpreter::_normal_table; DispatchTable TemplateInterpreter::_safept_table; address TemplateInterpreter::_wentry_point[DispatchTable::length]; - TemplateInterpreterGenerator::TemplateInterpreterGenerator(StubQueue* _code): AbstractInterpreterGenerator(_code) { - _unimplemented_bytecode = NULL; - _illegal_bytecode_sequence = NULL; - generate_all(); - } - - static const BasicType types[Interpreter::number_of_result_handlers] = { - T_BOOLEAN, - T_CHAR , - T_BYTE , - T_SHORT , - T_INT , - T_LONG , - T_VOID , - T_FLOAT , - T_DOUBLE , - T_OBJECT - }; - - void TemplateInterpreterGenerator::generate_all() { - // Loop, in case we need several variants of the interpreter entries - do { - if (!CodeCacheExtensions::skip_code_generation()) { - // bypass code generation when useless - AbstractInterpreterGenerator::generate_all(); - - { CodeletMark cm(_masm, "error exits"); - _unimplemented_bytecode = generate_error_exit("unimplemented bytecode"); - _illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified"); - } - - #ifndef PRODUCT - if (TraceBytecodes) { - CodeletMark cm(_masm, "bytecode tracing support"); - Interpreter::_trace_code = - EntryPoint( - generate_trace_code(btos), - generate_trace_code(ctos), - generate_trace_code(stos), - generate_trace_code(atos), - generate_trace_code(itos), - generate_trace_code(ltos), - generate_trace_code(ftos), - generate_trace_code(dtos), - generate_trace_code(vtos) - ); - } - #endif // !PRODUCT - - { CodeletMark cm(_masm, "return entry points"); - const int index_size = sizeof(u2); - for (int i = 0; i < Interpreter::number_of_return_entries; i++) { - Interpreter::_return_entry[i] = - EntryPoint( - generate_return_entry_for(itos, i, index_size), - generate_return_entry_for(itos, i, index_size), - generate_return_entry_for(itos, i, index_size), - generate_return_entry_for(atos, i, index_size), - generate_return_entry_for(itos, i, index_size), - generate_return_entry_for(ltos, i, index_size), - generate_return_entry_for(ftos, i, index_size), - generate_return_entry_for(dtos, i, index_size), - generate_return_entry_for(vtos, i, index_size) - ); - } - } - - { CodeletMark cm(_masm, "invoke return entry points"); - const TosState states[] = {itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos}; - const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic); - const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface); - const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic); - - for (int i = 0; i < Interpreter::number_of_return_addrs; i++) { - TosState state = states[i]; - Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2)); - Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2)); - Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4)); - } - } - - { CodeletMark cm(_masm, "earlyret entry points"); - Interpreter::_earlyret_entry = - EntryPoint( - generate_earlyret_entry_for(btos), - generate_earlyret_entry_for(ctos), - generate_earlyret_entry_for(stos), - generate_earlyret_entry_for(atos), - generate_earlyret_entry_for(itos), - generate_earlyret_entry_for(ltos), - generate_earlyret_entry_for(ftos), - generate_earlyret_entry_for(dtos), - generate_earlyret_entry_for(vtos) - ); - } - - { CodeletMark cm(_masm, "deoptimization entry points"); - for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) { - Interpreter::_deopt_entry[i] = - EntryPoint( - generate_deopt_entry_for(itos, i), - generate_deopt_entry_for(itos, i), - generate_deopt_entry_for(itos, i), - generate_deopt_entry_for(atos, i), - generate_deopt_entry_for(itos, i), - generate_deopt_entry_for(ltos, i), - generate_deopt_entry_for(ftos, i), - generate_deopt_entry_for(dtos, i), - generate_deopt_entry_for(vtos, i) - ); - } - } - - { CodeletMark cm(_masm, "result handlers for native calls"); - // The various result converter stublets. - int is_generated[Interpreter::number_of_result_handlers]; - memset(is_generated, 0, sizeof(is_generated)); - - for (int i = 0; i < Interpreter::number_of_result_handlers; i++) { - BasicType type = types[i]; - if (!is_generated[Interpreter::BasicType_as_index(type)]++) { - Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type); - } - } - } - - { CodeletMark cm(_masm, "continuation entry points"); - Interpreter::_continuation_entry = - EntryPoint( - generate_continuation_for(btos), - generate_continuation_for(ctos), - generate_continuation_for(stos), - generate_continuation_for(atos), - generate_continuation_for(itos), - generate_continuation_for(ltos), - generate_continuation_for(ftos), - generate_continuation_for(dtos), - generate_continuation_for(vtos) - ); - } - - { CodeletMark cm(_masm, "safepoint entry points"); - Interpreter::_safept_entry = - EntryPoint( - generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), - generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), - generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), - generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), - generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), - generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), - generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), - generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), - generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)) - ); - } - - { CodeletMark cm(_masm, "exception handling"); - // (Note: this is not safepoint safe because thread may return to compiled code) - generate_throw_exception(); - } - - { CodeletMark cm(_masm, "throw exception entrypoints"); - Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException"); - Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException" ); - Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException" , "/ by zero"); - Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler(); - Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException" , NULL ); - Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler(); - } - - - - #define method_entry(kind) \ - { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \ - Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind); \ - } - - // all non-native method kinds - method_entry(zerolocals) - method_entry(zerolocals_synchronized) - method_entry(empty) - method_entry(accessor) - method_entry(abstract) - method_entry(java_lang_math_sin ) - method_entry(java_lang_math_cos ) - method_entry(java_lang_math_tan ) - method_entry(java_lang_math_abs ) - method_entry(java_lang_math_sqrt ) - method_entry(java_lang_math_log ) - method_entry(java_lang_math_log10) - method_entry(java_lang_math_exp ) - method_entry(java_lang_math_pow ) - method_entry(java_lang_ref_reference_get) - - initialize_method_handle_entries(); - - // all native method kinds (must be one contiguous block) - Interpreter::_native_entry_begin = Interpreter::code()->code_end(); - method_entry(native) - method_entry(native_synchronized) - Interpreter::_native_entry_end = Interpreter::code()->code_end(); - - if (UseCRC32Intrinsics) { - method_entry(java_util_zip_CRC32_update) - method_entry(java_util_zip_CRC32_updateBytes) - method_entry(java_util_zip_CRC32_updateByteBuffer) - } - - if (UseCRC32CIntrinsics) { - method_entry(java_util_zip_CRC32C_updateBytes) - method_entry(java_util_zip_CRC32C_updateDirectByteBuffer) - } - - method_entry(java_lang_Float_intBitsToFloat); - method_entry(java_lang_Float_floatToRawIntBits); - method_entry(java_lang_Double_longBitsToDouble); - method_entry(java_lang_Double_doubleToRawLongBits); - - #undef method_entry - - // Bytecodes - set_entry_points_for_all_bytes(); - } - } while (CodeCacheExtensions::needs_other_interpreter_variant()); - - // installation of code in other places in the runtime - // (ExcutableCodeManager calls not needed to copy the entries) - set_safepoints_for_all_bytes(); - } - - //------------------------------------------------------------------------------------------------------------------------ - - address TemplateInterpreterGenerator::generate_error_exit(const char* msg) { - address entry = __ pc(); - __ stop(msg); - return entry; - } - - - //------------------------------------------------------------------------------------------------------------------------ - - void TemplateInterpreterGenerator::set_entry_points_for_all_bytes() { - for (int i = 0; i < DispatchTable::length; i++) { - Bytecodes::Code code = (Bytecodes::Code)i; - if (Bytecodes::is_defined(code)) { - set_entry_points(code); - } else { - set_unimplemented(i); - } - } - } - - - void TemplateInterpreterGenerator::set_safepoints_for_all_bytes() { - for (int i = 0; i < DispatchTable::length; i++) { - Bytecodes::Code code = (Bytecodes::Code)i; - if (Bytecodes::is_defined(code)) Interpreter::_safept_table.set_entry(code, Interpreter::_safept_entry); - } - } - - - void TemplateInterpreterGenerator::set_unimplemented(int i) { - address e = _unimplemented_bytecode; - EntryPoint entry(e, e, e, e, e, e, e, e, e); - Interpreter::_normal_table.set_entry(i, entry); - Interpreter::_wentry_point[i] = _unimplemented_bytecode; - } - - - void TemplateInterpreterGenerator::set_entry_points(Bytecodes::Code code) { - if (CodeCacheExtensions::skip_template_interpreter_entries(code)) { - return; - } - CodeletMark cm(_masm, Bytecodes::name(code), code); - // initialize entry points - assert(_unimplemented_bytecode != NULL, "should have been generated before"); - assert(_illegal_bytecode_sequence != NULL, "should have been generated before"); - address bep = _illegal_bytecode_sequence; - address cep = _illegal_bytecode_sequence; - address sep = _illegal_bytecode_sequence; - address aep = _illegal_bytecode_sequence; - address iep = _illegal_bytecode_sequence; - address lep = _illegal_bytecode_sequence; - address fep = _illegal_bytecode_sequence; - address dep = _illegal_bytecode_sequence; - address vep = _unimplemented_bytecode; - address wep = _unimplemented_bytecode; - // code for short & wide version of bytecode - if (Bytecodes::is_defined(code)) { - Template* t = TemplateTable::template_for(code); - assert(t->is_valid(), "just checking"); - set_short_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); - } - if (Bytecodes::wide_is_defined(code)) { - Template* t = TemplateTable::template_for_wide(code); - assert(t->is_valid(), "just checking"); - set_wide_entry_point(t, wep); - } - // set entry points - EntryPoint entry(bep, cep, sep, aep, iep, lep, fep, dep, vep); - Interpreter::_normal_table.set_entry(code, entry); - Interpreter::_wentry_point[code] = wep; - CodeCacheExtensions::completed_template_interpreter_entries(_masm, code); - } - - - void TemplateInterpreterGenerator::set_wide_entry_point(Template* t, address& wep) { - assert(t->is_valid(), "template must exist"); - assert(t->tos_in() == vtos, "only vtos tos_in supported for wide instructions"); - wep = __ pc(); generate_and_dispatch(t); - } - - - void TemplateInterpreterGenerator::set_short_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) { - assert(t->is_valid(), "template must exist"); - switch (t->tos_in()) { - case btos: - case ctos: - case stos: - ShouldNotReachHere(); // btos/ctos/stos should use itos. - break; - case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break; - case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break; - case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break; - case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break; - case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break; - case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); break; - default : ShouldNotReachHere(); break; - } - } - - - //------------------------------------------------------------------------------------------------------------------------ - - void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) { - if (PrintBytecodeHistogram) histogram_bytecode(t); - #ifndef PRODUCT - // debugging code - if (CountBytecodes || TraceBytecodes || StopInterpreterAt > 0) count_bytecode(); - if (PrintBytecodePairHistogram) histogram_bytecode_pair(t); - if (TraceBytecodes) trace_bytecode(t); - if (StopInterpreterAt > 0) stop_interpreter_at(); - __ verify_FPU(1, t->tos_in()); - #endif // !PRODUCT - int step = 0; - if (!t->does_dispatch()) { - step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode()); - if (tos_out == ilgl) tos_out = t->tos_out(); - // compute bytecode size - assert(step > 0, "just checkin'"); - // setup stuff for dispatching next bytecode - if (ProfileInterpreter && VerifyDataPointer - && MethodData::bytecode_has_profile(t->bytecode())) { - __ verify_method_data_pointer(); - } - __ dispatch_prolog(tos_out, step); - } - // generate template - t->generate(_masm); - // advance - if (t->does_dispatch()) { - #ifdef ASSERT - // make sure execution doesn't go beyond this point if code is broken - __ should_not_reach_here(); - #endif // ASSERT - } else { - // dispatch to next bytecode - __ dispatch_epilog(tos_out, step); - } - } //------------------------------------------------------------------------------------------------------------------------ // Entry points /** --- 218,227 ----
*** 722,808 **** InterpreterCodelet* TemplateInterpreter::codelet_containing(address pc) { return (InterpreterCodelet*)_code->stub_containing(pc); } - // Generate method entries - address TemplateInterpreterGenerator::generate_method_entry( - AbstractInterpreter::MethodKind kind) { - // determine code generation flags - bool native = false; - bool synchronized = false; - address entry_point = NULL; - - switch (kind) { - case Interpreter::zerolocals : break; - case Interpreter::zerolocals_synchronized: synchronized = true; break; - case Interpreter::native : native = true; break; - case Interpreter::native_synchronized : native = true; synchronized = true; break; - case Interpreter::empty : break; - case Interpreter::accessor : break; - case Interpreter::abstract : entry_point = generate_abstract_entry(); break; - - case Interpreter::java_lang_math_sin : // fall thru - case Interpreter::java_lang_math_cos : // fall thru - case Interpreter::java_lang_math_tan : // fall thru - case Interpreter::java_lang_math_abs : // fall thru - case Interpreter::java_lang_math_log : // fall thru - case Interpreter::java_lang_math_log10 : // fall thru - case Interpreter::java_lang_math_sqrt : // fall thru - case Interpreter::java_lang_math_pow : // fall thru - case Interpreter::java_lang_math_exp : entry_point = generate_math_entry(kind); break; - case Interpreter::java_lang_ref_reference_get - : entry_point = generate_Reference_get_entry(); break; - case Interpreter::java_util_zip_CRC32_update - : native = true; entry_point = generate_CRC32_update_entry(); break; - case Interpreter::java_util_zip_CRC32_updateBytes - : // fall thru - case Interpreter::java_util_zip_CRC32_updateByteBuffer - : native = true; entry_point = generate_CRC32_updateBytes_entry(kind); break; - case Interpreter::java_util_zip_CRC32C_updateBytes - : // fall thru - case Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer - : entry_point = generate_CRC32C_updateBytes_entry(kind); break; - #ifdef IA32 - // On x86_32 platforms, a special entry is generated for the following four methods. - // On other platforms the normal entry is used to enter these methods. - case Interpreter::java_lang_Float_intBitsToFloat - : native = true; entry_point = generate_Float_intBitsToFloat_entry(); break; - case Interpreter::java_lang_Float_floatToRawIntBits - : native = true; entry_point = generate_Float_floatToRawIntBits_entry(); break; - case Interpreter::java_lang_Double_longBitsToDouble - : native = true; entry_point = generate_Double_longBitsToDouble_entry(); break; - case Interpreter::java_lang_Double_doubleToRawLongBits - : native = true; entry_point = generate_Double_doubleToRawLongBits_entry(); break; - #else - case Interpreter::java_lang_Float_intBitsToFloat: - case Interpreter::java_lang_Float_floatToRawIntBits: - case Interpreter::java_lang_Double_longBitsToDouble: - case Interpreter::java_lang_Double_doubleToRawLongBits: - native = true; - break; - #endif // defined(TARGET_ARCH_x86) && !defined(_LP64) - default: - fatal("unexpected method kind: %d", kind); - break; - } - - if (entry_point) { - return entry_point; - } - - // We expect the normal and native entry points to be generated first so we can reuse them. - if (native) { - entry_point = Interpreter::entry_for_kind(synchronized ? Interpreter::native_synchronized : Interpreter::native); - if (entry_point == NULL) { - entry_point = generate_native_entry(synchronized); - } - } else { - entry_point = Interpreter::entry_for_kind(synchronized ? Interpreter::zerolocals_synchronized : Interpreter::zerolocals); - if (entry_point == NULL) { - entry_point = generate_normal_entry(synchronized); - } - } - - return entry_point; - } #endif // !CC_INTERP --- 353,358 ----
< prev index next >