Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/interpreter/templateInterpreter.cpp
32285 views
/*1* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "interpreter/interpreter.hpp"26#include "interpreter/interpreterGenerator.hpp"27#include "interpreter/interpreterRuntime.hpp"28#include "interpreter/templateTable.hpp"2930#ifndef CC_INTERP3132# define __ _masm->3334void TemplateInterpreter::initialize() {35if (_code != NULL) return;36// assertions37assert((int)Bytecodes::number_of_codes <= (int)DispatchTable::length,38"dispatch table too small");3940AbstractInterpreter::initialize();4142TemplateTable::initialize();4344// generate interpreter45{ ResourceMark rm;46TraceTime timer("Interpreter generation", TraceStartupTime);47int code_size = InterpreterCodeSize;48NOT_PRODUCT(code_size *= 4;) // debug uses extra interpreter code space49_code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL,50"Interpreter");51InterpreterGenerator g(_code);52if (PrintInterpreter) print();53}5455// initialize dispatch table56_active_table = _normal_table;57}5859//------------------------------------------------------------------------------------------------------------------------60// Implementation of EntryPoint6162EntryPoint::EntryPoint() {63assert(number_of_states == 10, "check the code below");64_entry[btos] = NULL;65_entry[ztos] = NULL;66_entry[ctos] = NULL;67_entry[stos] = NULL;68_entry[atos] = NULL;69_entry[itos] = NULL;70_entry[ltos] = NULL;71_entry[ftos] = NULL;72_entry[dtos] = NULL;73_entry[vtos] = NULL;74}757677EntryPoint::EntryPoint(address bentry, address zentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) {78assert(number_of_states == 10, "check the code below");79_entry[btos] = bentry;80_entry[ztos] = zentry;81_entry[ctos] = centry;82_entry[stos] = sentry;83_entry[atos] = aentry;84_entry[itos] = ientry;85_entry[ltos] = lentry;86_entry[ftos] = fentry;87_entry[dtos] = dentry;88_entry[vtos] = ventry;89}909192void EntryPoint::set_entry(TosState state, address entry) {93assert(0 <= state && state < number_of_states, "state out of bounds");94_entry[state] = entry;95}969798address EntryPoint::entry(TosState state) const {99assert(0 <= state && state < number_of_states, "state out of bounds");100return _entry[state];101}102103104void EntryPoint::print() {105tty->print("[");106for (int i = 0; i < number_of_states; i++) {107if (i > 0) tty->print(", ");108tty->print(INTPTR_FORMAT, p2i(_entry[i]));109}110tty->print("]");111}112113114bool EntryPoint::operator == (const EntryPoint& y) {115int i = number_of_states;116while (i-- > 0) {117if (_entry[i] != y._entry[i]) return false;118}119return true;120}121122123//------------------------------------------------------------------------------------------------------------------------124// Implementation of DispatchTable125126EntryPoint DispatchTable::entry(int i) const {127assert(0 <= i && i < length, "index out of bounds");128return129EntryPoint(130_table[btos][i],131_table[ztos][i],132_table[ctos][i],133_table[stos][i],134_table[atos][i],135_table[itos][i],136_table[ltos][i],137_table[ftos][i],138_table[dtos][i],139_table[vtos][i]140);141}142143144void DispatchTable::set_entry(int i, EntryPoint& entry) {145assert(0 <= i && i < length, "index out of bounds");146assert(number_of_states == 10, "check the code below");147_table[btos][i] = entry.entry(btos);148_table[ztos][i] = entry.entry(ztos);149_table[ctos][i] = entry.entry(ctos);150_table[stos][i] = entry.entry(stos);151_table[atos][i] = entry.entry(atos);152_table[itos][i] = entry.entry(itos);153_table[ltos][i] = entry.entry(ltos);154_table[ftos][i] = entry.entry(ftos);155_table[dtos][i] = entry.entry(dtos);156_table[vtos][i] = entry.entry(vtos);157}158159160bool DispatchTable::operator == (DispatchTable& y) {161int i = length;162while (i-- > 0) {163EntryPoint t = y.entry(i); // for compiler compatibility (BugId 4150096)164if (!(entry(i) == t)) return false;165}166return true;167}168169address TemplateInterpreter::_remove_activation_entry = NULL;170address TemplateInterpreter::_remove_activation_preserving_args_entry = NULL;171172173address TemplateInterpreter::_throw_ArrayIndexOutOfBoundsException_entry = NULL;174address TemplateInterpreter::_throw_ArrayStoreException_entry = NULL;175address TemplateInterpreter::_throw_ArithmeticException_entry = NULL;176address TemplateInterpreter::_throw_ClassCastException_entry = NULL;177address TemplateInterpreter::_throw_NullPointerException_entry = NULL;178address TemplateInterpreter::_throw_StackOverflowError_entry = NULL;179address TemplateInterpreter::_throw_exception_entry = NULL;180181#ifndef PRODUCT182EntryPoint TemplateInterpreter::_trace_code;183#endif // !PRODUCT184EntryPoint TemplateInterpreter::_return_entry[TemplateInterpreter::number_of_return_entries];185EntryPoint TemplateInterpreter::_earlyret_entry;186EntryPoint TemplateInterpreter::_deopt_entry [TemplateInterpreter::number_of_deopt_entries ];187EntryPoint TemplateInterpreter::_continuation_entry;188EntryPoint TemplateInterpreter::_safept_entry;189190address TemplateInterpreter::_invoke_return_entry[TemplateInterpreter::number_of_return_addrs];191address TemplateInterpreter::_invokeinterface_return_entry[TemplateInterpreter::number_of_return_addrs];192address TemplateInterpreter::_invokedynamic_return_entry[TemplateInterpreter::number_of_return_addrs];193194DispatchTable TemplateInterpreter::_active_table;195DispatchTable TemplateInterpreter::_normal_table;196DispatchTable TemplateInterpreter::_safept_table;197address TemplateInterpreter::_wentry_point[DispatchTable::length];198199TemplateInterpreterGenerator::TemplateInterpreterGenerator(StubQueue* _code): AbstractInterpreterGenerator(_code) {200_unimplemented_bytecode = NULL;201_illegal_bytecode_sequence = NULL;202}203204static const BasicType types[Interpreter::number_of_result_handlers] = {205T_BOOLEAN,206T_CHAR ,207T_BYTE ,208T_SHORT ,209T_INT ,210T_LONG ,211T_VOID ,212T_FLOAT ,213T_DOUBLE ,214T_OBJECT215};216217void TemplateInterpreterGenerator::generate_all() {218AbstractInterpreterGenerator::generate_all();219220{ CodeletMark cm(_masm, "error exits");221_unimplemented_bytecode = generate_error_exit("unimplemented bytecode");222_illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified");223}224225#ifndef PRODUCT226if (TraceBytecodes) {227CodeletMark cm(_masm, "bytecode tracing support");228Interpreter::_trace_code =229EntryPoint(230generate_trace_code(btos),231generate_trace_code(ztos),232generate_trace_code(ctos),233generate_trace_code(stos),234generate_trace_code(atos),235generate_trace_code(itos),236generate_trace_code(ltos),237generate_trace_code(ftos),238generate_trace_code(dtos),239generate_trace_code(vtos)240);241}242#endif // !PRODUCT243244{ CodeletMark cm(_masm, "return entry points");245const int index_size = sizeof(u2);246for (int i = 0; i < Interpreter::number_of_return_entries; i++) {247Interpreter::_return_entry[i] =248EntryPoint(249generate_return_entry_for(itos, i, index_size),250generate_return_entry_for(itos, i, index_size),251generate_return_entry_for(itos, i, index_size),252generate_return_entry_for(itos, i, index_size),253generate_return_entry_for(atos, i, index_size),254generate_return_entry_for(itos, i, index_size),255generate_return_entry_for(ltos, i, index_size),256generate_return_entry_for(ftos, i, index_size),257generate_return_entry_for(dtos, i, index_size),258generate_return_entry_for(vtos, i, index_size)259);260}261}262263{ CodeletMark cm(_masm, "invoke return entry points");264// These states are in order specified in TosState, except btos/ztos/ctos/stos are265// really the same as itos since there is no top of stack optimization for these types266const TosState states[] = {itos, itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos, ilgl};267const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic);268const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface);269const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic);270271for (int i = 0; i < Interpreter::number_of_return_addrs; i++) {272TosState state = states[i];273assert(state != ilgl, "states array is wrong above");274Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2));275Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2));276Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4));277}278}279280{ CodeletMark cm(_masm, "earlyret entry points");281Interpreter::_earlyret_entry =282EntryPoint(283generate_earlyret_entry_for(btos),284generate_earlyret_entry_for(ztos),285generate_earlyret_entry_for(ctos),286generate_earlyret_entry_for(stos),287generate_earlyret_entry_for(atos),288generate_earlyret_entry_for(itos),289generate_earlyret_entry_for(ltos),290generate_earlyret_entry_for(ftos),291generate_earlyret_entry_for(dtos),292generate_earlyret_entry_for(vtos)293);294}295296{ CodeletMark cm(_masm, "deoptimization entry points");297for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) {298Interpreter::_deopt_entry[i] =299EntryPoint(300generate_deopt_entry_for(itos, i),301generate_deopt_entry_for(itos, i),302generate_deopt_entry_for(itos, i),303generate_deopt_entry_for(itos, i),304generate_deopt_entry_for(atos, i),305generate_deopt_entry_for(itos, i),306generate_deopt_entry_for(ltos, i),307generate_deopt_entry_for(ftos, i),308generate_deopt_entry_for(dtos, i),309generate_deopt_entry_for(vtos, i)310);311}312}313314{ CodeletMark cm(_masm, "result handlers for native calls");315// The various result converter stublets.316int is_generated[Interpreter::number_of_result_handlers];317memset(is_generated, 0, sizeof(is_generated));318319for (int i = 0; i < Interpreter::number_of_result_handlers; i++) {320BasicType type = types[i];321if (!is_generated[Interpreter::BasicType_as_index(type)]++) {322Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type);323}324}325}326327{ CodeletMark cm(_masm, "continuation entry points");328Interpreter::_continuation_entry =329EntryPoint(330generate_continuation_for(btos),331generate_continuation_for(ztos),332generate_continuation_for(ctos),333generate_continuation_for(stos),334generate_continuation_for(atos),335generate_continuation_for(itos),336generate_continuation_for(ltos),337generate_continuation_for(ftos),338generate_continuation_for(dtos),339generate_continuation_for(vtos)340);341}342343{ CodeletMark cm(_masm, "safepoint entry points");344Interpreter::_safept_entry =345EntryPoint(346generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),347generate_safept_entry_for(ztos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),348generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),349generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),350generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),351generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),352generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),353generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),354generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),355generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint))356);357}358359{ CodeletMark cm(_masm, "exception handling");360// (Note: this is not safepoint safe because thread may return to compiled code)361generate_throw_exception();362}363364{ CodeletMark cm(_masm, "throw exception entrypoints");365Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException");366Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException" );367Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException" , "/ by zero");368Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler();369Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException" , NULL );370Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler();371}372373374375#define method_entry(kind) \376{ CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \377Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind); \378}379380// all non-native method kinds381method_entry(zerolocals)382method_entry(zerolocals_synchronized)383method_entry(empty)384method_entry(accessor)385method_entry(abstract)386method_entry(java_lang_math_sin )387method_entry(java_lang_math_cos )388method_entry(java_lang_math_tan )389method_entry(java_lang_math_abs )390method_entry(java_lang_math_sqrt )391method_entry(java_lang_math_log )392method_entry(java_lang_math_log10)393method_entry(java_lang_math_exp )394method_entry(java_lang_math_pow )395method_entry(java_lang_ref_reference_get)396397if (UseCRC32Intrinsics) {398method_entry(java_util_zip_CRC32_update)399method_entry(java_util_zip_CRC32_updateBytes)400method_entry(java_util_zip_CRC32_updateByteBuffer)401}402403initialize_method_handle_entries();404405// all native method kinds (must be one contiguous block)406Interpreter::_native_entry_begin = Interpreter::code()->code_end();407method_entry(native)408method_entry(native_synchronized)409Interpreter::_native_entry_end = Interpreter::code()->code_end();410411#undef method_entry412413// Bytecodes414set_entry_points_for_all_bytes();415set_safepoints_for_all_bytes();416}417418//------------------------------------------------------------------------------------------------------------------------419420address TemplateInterpreterGenerator::generate_error_exit(const char* msg) {421address entry = __ pc();422__ stop(msg);423return entry;424}425426427//------------------------------------------------------------------------------------------------------------------------428429void TemplateInterpreterGenerator::set_entry_points_for_all_bytes() {430for (int i = 0; i < DispatchTable::length; i++) {431Bytecodes::Code code = (Bytecodes::Code)i;432if (Bytecodes::is_defined(code)) {433set_entry_points(code);434} else {435set_unimplemented(i);436}437}438}439440441void TemplateInterpreterGenerator::set_safepoints_for_all_bytes() {442for (int i = 0; i < DispatchTable::length; i++) {443Bytecodes::Code code = (Bytecodes::Code)i;444if (Bytecodes::is_defined(code)) Interpreter::_safept_table.set_entry(code, Interpreter::_safept_entry);445}446}447448449void TemplateInterpreterGenerator::set_unimplemented(int i) {450address e = _unimplemented_bytecode;451EntryPoint entry(e, e, e, e, e, e, e, e, e, e);452Interpreter::_normal_table.set_entry(i, entry);453Interpreter::_wentry_point[i] = _unimplemented_bytecode;454}455456457void TemplateInterpreterGenerator::set_entry_points(Bytecodes::Code code) {458CodeletMark cm(_masm, Bytecodes::name(code), code);459// initialize entry points460assert(_unimplemented_bytecode != NULL, "should have been generated before");461assert(_illegal_bytecode_sequence != NULL, "should have been generated before");462address bep = _illegal_bytecode_sequence;463address zep = _illegal_bytecode_sequence;464address cep = _illegal_bytecode_sequence;465address sep = _illegal_bytecode_sequence;466address aep = _illegal_bytecode_sequence;467address iep = _illegal_bytecode_sequence;468address lep = _illegal_bytecode_sequence;469address fep = _illegal_bytecode_sequence;470address dep = _illegal_bytecode_sequence;471address vep = _unimplemented_bytecode;472address wep = _unimplemented_bytecode;473// code for short & wide version of bytecode474if (Bytecodes::is_defined(code)) {475Template* t = TemplateTable::template_for(code);476assert(t->is_valid(), "just checking");477set_short_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep);478}479if (Bytecodes::wide_is_defined(code)) {480Template* t = TemplateTable::template_for_wide(code);481assert(t->is_valid(), "just checking");482set_wide_entry_point(t, wep);483}484// set entry points485EntryPoint entry(bep, zep, cep, sep, aep, iep, lep, fep, dep, vep);486Interpreter::_normal_table.set_entry(code, entry);487Interpreter::_wentry_point[code] = wep;488}489490491void TemplateInterpreterGenerator::set_wide_entry_point(Template* t, address& wep) {492assert(t->is_valid(), "template must exist");493assert(t->tos_in() == vtos, "only vtos tos_in supported for wide instructions");494wep = __ pc(); generate_and_dispatch(t);495}496497498void 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) {499assert(t->is_valid(), "template must exist");500switch (t->tos_in()) {501case btos:502case ztos:503case ctos:504case stos:505ShouldNotReachHere(); // btos/ctos/stos should use itos.506break;507case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break;508case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break;509case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break;510case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break;511case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break;512case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); break;513default : ShouldNotReachHere(); break;514}515}516517518//------------------------------------------------------------------------------------------------------------------------519520void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) {521if (PrintBytecodeHistogram) histogram_bytecode(t);522#ifndef PRODUCT523// debugging code524if (CountBytecodes || TraceBytecodes || StopInterpreterAt > 0) count_bytecode();525if (PrintBytecodePairHistogram) histogram_bytecode_pair(t);526if (TraceBytecodes) trace_bytecode(t);527if (StopInterpreterAt > 0) stop_interpreter_at();528__ verify_FPU(1, t->tos_in());529#endif // !PRODUCT530int step = 0;531if (!t->does_dispatch()) {532step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode());533if (tos_out == ilgl) tos_out = t->tos_out();534// compute bytecode size535assert(step > 0, "just checkin'");536// setup stuff for dispatching next bytecode537if (ProfileInterpreter && VerifyDataPointer538&& MethodData::bytecode_has_profile(t->bytecode())) {539__ verify_method_data_pointer();540}541__ dispatch_prolog(tos_out, step);542}543// generate template544t->generate(_masm);545// advance546if (t->does_dispatch()) {547#ifdef ASSERT548// make sure execution doesn't go beyond this point if code is broken549__ should_not_reach_here();550#endif // ASSERT551} else {552// dispatch to next bytecode553__ dispatch_epilog(tos_out, step);554}555}556557//------------------------------------------------------------------------------------------------------------------------558// Entry points559560/**561* Returns the return entry table for the given invoke bytecode.562*/563address* TemplateInterpreter::invoke_return_entry_table_for(Bytecodes::Code code) {564switch (code) {565case Bytecodes::_invokestatic:566case Bytecodes::_invokespecial:567case Bytecodes::_invokevirtual:568case Bytecodes::_invokehandle:569return Interpreter::invoke_return_entry_table();570case Bytecodes::_invokeinterface:571return Interpreter::invokeinterface_return_entry_table();572case Bytecodes::_invokedynamic:573return Interpreter::invokedynamic_return_entry_table();574default:575fatal(err_msg("invalid bytecode: %s", Bytecodes::name(code)));576return NULL;577}578}579580/**581* Returns the return entry address for the given top-of-stack state and bytecode.582*/583address TemplateInterpreter::return_entry(TosState state, int length, Bytecodes::Code code) {584guarantee(0 <= length && length < Interpreter::number_of_return_entries, "illegal length");585const int index = TosState_as_index(state);586switch (code) {587case Bytecodes::_invokestatic:588case Bytecodes::_invokespecial:589case Bytecodes::_invokevirtual:590case Bytecodes::_invokehandle:591return _invoke_return_entry[index];592case Bytecodes::_invokeinterface:593return _invokeinterface_return_entry[index];594case Bytecodes::_invokedynamic:595return _invokedynamic_return_entry[index];596default:597assert(!Bytecodes::is_invoke(code), err_msg("invoke instructions should be handled separately: %s", Bytecodes::name(code)));598return _return_entry[length].entry(state);599}600}601602603address TemplateInterpreter::deopt_entry(TosState state, int length) {604guarantee(0 <= length && length < Interpreter::number_of_deopt_entries, "illegal length");605return _deopt_entry[length].entry(state);606}607608//------------------------------------------------------------------------------------------------------------------------609// Suport for invokes610611int TemplateInterpreter::TosState_as_index(TosState state) {612assert( state < number_of_states , "Invalid state in TosState_as_index");613assert(0 <= (int)state && (int)state < TemplateInterpreter::number_of_return_addrs, "index out of bounds");614return (int)state;615}616617618//------------------------------------------------------------------------------------------------------------------------619// Safepoint suppport620621static inline void copy_table(address* from, address* to, int size) {622// Copy non-overlapping tables. The copy has to occur word wise for MT safety.623while (size-- > 0) *to++ = *from++;624}625626void TemplateInterpreter::notice_safepoints() {627if (!_notice_safepoints) {628// switch to safepoint dispatch table629_notice_safepoints = true;630copy_table((address*)&_safept_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address));631}632}633634// switch from the dispatch table which notices safepoints back to the635// normal dispatch table. So that we can notice single stepping points,636// keep the safepoint dispatch table if we are single stepping in JVMTI.637// Note that the should_post_single_step test is exactly as fast as the638// JvmtiExport::_enabled test and covers both cases.639void TemplateInterpreter::ignore_safepoints() {640if (_notice_safepoints) {641if (!JvmtiExport::should_post_single_step()) {642// switch to normal dispatch table643_notice_safepoints = false;644copy_table((address*)&_normal_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address));645}646}647}648649//------------------------------------------------------------------------------------------------------------------------650// Deoptimization support651652// If deoptimization happens, this function returns the point of next bytecode to continue execution653address TemplateInterpreter::deopt_continue_after_entry(Method* method, address bcp, int callee_parameters, bool is_top_frame) {654return AbstractInterpreter::deopt_continue_after_entry(method, bcp, callee_parameters, is_top_frame);655}656657// If deoptimization happens, this function returns the point where the interpreter reexecutes658// the bytecode.659// Note: Bytecodes::_athrow (C1 only) and Bytecodes::_return are the special cases660// that do not return "Interpreter::deopt_entry(vtos, 0)"661address TemplateInterpreter::deopt_reexecute_entry(Method* method, address bcp) {662assert(method->contains(bcp), "just checkin'");663Bytecodes::Code code = Bytecodes::java_code_at(method, bcp);664if (code == Bytecodes::_return) {665// This is used for deopt during registration of finalizers666// during Object.<init>. We simply need to resume execution at667// the standard return vtos bytecode to pop the frame normally.668// reexecuting the real bytecode would cause double registration669// of the finalizable object.670return _normal_table.entry(Bytecodes::_return).entry(vtos);671} else {672return AbstractInterpreter::deopt_reexecute_entry(method, bcp);673}674}675676// If deoptimization happens, the interpreter should reexecute this bytecode.677// This function mainly helps the compilers to set up the reexecute bit.678bool TemplateInterpreter::bytecode_should_reexecute(Bytecodes::Code code) {679if (code == Bytecodes::_return) {680//Yes, we consider Bytecodes::_return as a special case of reexecution681return true;682} else {683return AbstractInterpreter::bytecode_should_reexecute(code);684}685}686687#endif // !CC_INTERP688689690