1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/interpreter/templateInterpreter.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,673 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "interpreter/interpreter.hpp" 1.30 +#include "interpreter/interpreterGenerator.hpp" 1.31 +#include "interpreter/interpreterRuntime.hpp" 1.32 +#include "interpreter/templateTable.hpp" 1.33 + 1.34 +#ifndef CC_INTERP 1.35 + 1.36 +# define __ _masm-> 1.37 + 1.38 +void TemplateInterpreter::initialize() { 1.39 + if (_code != NULL) return; 1.40 + // assertions 1.41 + assert((int)Bytecodes::number_of_codes <= (int)DispatchTable::length, 1.42 + "dispatch table too small"); 1.43 + 1.44 + AbstractInterpreter::initialize(); 1.45 + 1.46 + TemplateTable::initialize(); 1.47 + 1.48 + // generate interpreter 1.49 + { ResourceMark rm; 1.50 + TraceTime timer("Interpreter generation", TraceStartupTime); 1.51 + int code_size = InterpreterCodeSize; 1.52 + NOT_PRODUCT(code_size *= 4;) // debug uses extra interpreter code space 1.53 + _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL, 1.54 + "Interpreter"); 1.55 + InterpreterGenerator g(_code); 1.56 + if (PrintInterpreter) print(); 1.57 + } 1.58 + 1.59 + // initialize dispatch table 1.60 + _active_table = _normal_table; 1.61 +} 1.62 + 1.63 +//------------------------------------------------------------------------------------------------------------------------ 1.64 +// Implementation of EntryPoint 1.65 + 1.66 +EntryPoint::EntryPoint() { 1.67 + assert(number_of_states == 9, "check the code below"); 1.68 + _entry[btos] = NULL; 1.69 + _entry[ctos] = NULL; 1.70 + _entry[stos] = NULL; 1.71 + _entry[atos] = NULL; 1.72 + _entry[itos] = NULL; 1.73 + _entry[ltos] = NULL; 1.74 + _entry[ftos] = NULL; 1.75 + _entry[dtos] = NULL; 1.76 + _entry[vtos] = NULL; 1.77 +} 1.78 + 1.79 + 1.80 +EntryPoint::EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) { 1.81 + assert(number_of_states == 9, "check the code below"); 1.82 + _entry[btos] = bentry; 1.83 + _entry[ctos] = centry; 1.84 + _entry[stos] = sentry; 1.85 + _entry[atos] = aentry; 1.86 + _entry[itos] = ientry; 1.87 + _entry[ltos] = lentry; 1.88 + _entry[ftos] = fentry; 1.89 + _entry[dtos] = dentry; 1.90 + _entry[vtos] = ventry; 1.91 +} 1.92 + 1.93 + 1.94 +void EntryPoint::set_entry(TosState state, address entry) { 1.95 + assert(0 <= state && state < number_of_states, "state out of bounds"); 1.96 + _entry[state] = entry; 1.97 +} 1.98 + 1.99 + 1.100 +address EntryPoint::entry(TosState state) const { 1.101 + assert(0 <= state && state < number_of_states, "state out of bounds"); 1.102 + return _entry[state]; 1.103 +} 1.104 + 1.105 + 1.106 +void EntryPoint::print() { 1.107 + tty->print("["); 1.108 + for (int i = 0; i < number_of_states; i++) { 1.109 + if (i > 0) tty->print(", "); 1.110 + tty->print(INTPTR_FORMAT, p2i(_entry[i])); 1.111 + } 1.112 + tty->print("]"); 1.113 +} 1.114 + 1.115 + 1.116 +bool EntryPoint::operator == (const EntryPoint& y) { 1.117 + int i = number_of_states; 1.118 + while (i-- > 0) { 1.119 + if (_entry[i] != y._entry[i]) return false; 1.120 + } 1.121 + return true; 1.122 +} 1.123 + 1.124 + 1.125 +//------------------------------------------------------------------------------------------------------------------------ 1.126 +// Implementation of DispatchTable 1.127 + 1.128 +EntryPoint DispatchTable::entry(int i) const { 1.129 + assert(0 <= i && i < length, "index out of bounds"); 1.130 + return 1.131 + EntryPoint( 1.132 + _table[btos][i], 1.133 + _table[ctos][i], 1.134 + _table[stos][i], 1.135 + _table[atos][i], 1.136 + _table[itos][i], 1.137 + _table[ltos][i], 1.138 + _table[ftos][i], 1.139 + _table[dtos][i], 1.140 + _table[vtos][i] 1.141 + ); 1.142 +} 1.143 + 1.144 + 1.145 +void DispatchTable::set_entry(int i, EntryPoint& entry) { 1.146 + assert(0 <= i && i < length, "index out of bounds"); 1.147 + assert(number_of_states == 9, "check the code below"); 1.148 + _table[btos][i] = entry.entry(btos); 1.149 + _table[ctos][i] = entry.entry(ctos); 1.150 + _table[stos][i] = entry.entry(stos); 1.151 + _table[atos][i] = entry.entry(atos); 1.152 + _table[itos][i] = entry.entry(itos); 1.153 + _table[ltos][i] = entry.entry(ltos); 1.154 + _table[ftos][i] = entry.entry(ftos); 1.155 + _table[dtos][i] = entry.entry(dtos); 1.156 + _table[vtos][i] = entry.entry(vtos); 1.157 +} 1.158 + 1.159 + 1.160 +bool DispatchTable::operator == (DispatchTable& y) { 1.161 + int i = length; 1.162 + while (i-- > 0) { 1.163 + EntryPoint t = y.entry(i); // for compiler compatibility (BugId 4150096) 1.164 + if (!(entry(i) == t)) return false; 1.165 + } 1.166 + return true; 1.167 +} 1.168 + 1.169 +address TemplateInterpreter::_remove_activation_entry = NULL; 1.170 +address TemplateInterpreter::_remove_activation_preserving_args_entry = NULL; 1.171 + 1.172 + 1.173 +address TemplateInterpreter::_throw_ArrayIndexOutOfBoundsException_entry = NULL; 1.174 +address TemplateInterpreter::_throw_ArrayStoreException_entry = NULL; 1.175 +address TemplateInterpreter::_throw_ArithmeticException_entry = NULL; 1.176 +address TemplateInterpreter::_throw_ClassCastException_entry = NULL; 1.177 +address TemplateInterpreter::_throw_NullPointerException_entry = NULL; 1.178 +address TemplateInterpreter::_throw_StackOverflowError_entry = NULL; 1.179 +address TemplateInterpreter::_throw_exception_entry = NULL; 1.180 + 1.181 +#ifndef PRODUCT 1.182 +EntryPoint TemplateInterpreter::_trace_code; 1.183 +#endif // !PRODUCT 1.184 +EntryPoint TemplateInterpreter::_return_entry[TemplateInterpreter::number_of_return_entries]; 1.185 +EntryPoint TemplateInterpreter::_earlyret_entry; 1.186 +EntryPoint TemplateInterpreter::_deopt_entry [TemplateInterpreter::number_of_deopt_entries ]; 1.187 +EntryPoint TemplateInterpreter::_continuation_entry; 1.188 +EntryPoint TemplateInterpreter::_safept_entry; 1.189 + 1.190 +address TemplateInterpreter::_invoke_return_entry[TemplateInterpreter::number_of_return_addrs]; 1.191 +address TemplateInterpreter::_invokeinterface_return_entry[TemplateInterpreter::number_of_return_addrs]; 1.192 +address TemplateInterpreter::_invokedynamic_return_entry[TemplateInterpreter::number_of_return_addrs]; 1.193 + 1.194 +DispatchTable TemplateInterpreter::_active_table; 1.195 +DispatchTable TemplateInterpreter::_normal_table; 1.196 +DispatchTable TemplateInterpreter::_safept_table; 1.197 +address TemplateInterpreter::_wentry_point[DispatchTable::length]; 1.198 + 1.199 +TemplateInterpreterGenerator::TemplateInterpreterGenerator(StubQueue* _code): AbstractInterpreterGenerator(_code) { 1.200 + _unimplemented_bytecode = NULL; 1.201 + _illegal_bytecode_sequence = NULL; 1.202 +} 1.203 + 1.204 +static const BasicType types[Interpreter::number_of_result_handlers] = { 1.205 + T_BOOLEAN, 1.206 + T_CHAR , 1.207 + T_BYTE , 1.208 + T_SHORT , 1.209 + T_INT , 1.210 + T_LONG , 1.211 + T_VOID , 1.212 + T_FLOAT , 1.213 + T_DOUBLE , 1.214 + T_OBJECT 1.215 +}; 1.216 + 1.217 +void TemplateInterpreterGenerator::generate_all() { 1.218 + AbstractInterpreterGenerator::generate_all(); 1.219 + 1.220 + { CodeletMark cm(_masm, "error exits"); 1.221 + _unimplemented_bytecode = generate_error_exit("unimplemented bytecode"); 1.222 + _illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified"); 1.223 + } 1.224 + 1.225 +#ifndef PRODUCT 1.226 + if (TraceBytecodes) { 1.227 + CodeletMark cm(_masm, "bytecode tracing support"); 1.228 + Interpreter::_trace_code = 1.229 + EntryPoint( 1.230 + generate_trace_code(btos), 1.231 + generate_trace_code(ctos), 1.232 + generate_trace_code(stos), 1.233 + generate_trace_code(atos), 1.234 + generate_trace_code(itos), 1.235 + generate_trace_code(ltos), 1.236 + generate_trace_code(ftos), 1.237 + generate_trace_code(dtos), 1.238 + generate_trace_code(vtos) 1.239 + ); 1.240 + } 1.241 +#endif // !PRODUCT 1.242 + 1.243 + { CodeletMark cm(_masm, "return entry points"); 1.244 + const int index_size = sizeof(u2); 1.245 + for (int i = 0; i < Interpreter::number_of_return_entries; i++) { 1.246 + Interpreter::_return_entry[i] = 1.247 + EntryPoint( 1.248 + generate_return_entry_for(itos, i, index_size), 1.249 + generate_return_entry_for(itos, i, index_size), 1.250 + generate_return_entry_for(itos, i, index_size), 1.251 + generate_return_entry_for(atos, i, index_size), 1.252 + generate_return_entry_for(itos, i, index_size), 1.253 + generate_return_entry_for(ltos, i, index_size), 1.254 + generate_return_entry_for(ftos, i, index_size), 1.255 + generate_return_entry_for(dtos, i, index_size), 1.256 + generate_return_entry_for(vtos, i, index_size) 1.257 + ); 1.258 + } 1.259 + } 1.260 + 1.261 + { CodeletMark cm(_masm, "invoke return entry points"); 1.262 + const TosState states[] = {itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos}; 1.263 + const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic); 1.264 + const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface); 1.265 + const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic); 1.266 + 1.267 + for (int i = 0; i < Interpreter::number_of_return_addrs; i++) { 1.268 + TosState state = states[i]; 1.269 + Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2)); 1.270 + Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2)); 1.271 + Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4)); 1.272 + } 1.273 + } 1.274 + 1.275 + { CodeletMark cm(_masm, "earlyret entry points"); 1.276 + Interpreter::_earlyret_entry = 1.277 + EntryPoint( 1.278 + generate_earlyret_entry_for(btos), 1.279 + generate_earlyret_entry_for(ctos), 1.280 + generate_earlyret_entry_for(stos), 1.281 + generate_earlyret_entry_for(atos), 1.282 + generate_earlyret_entry_for(itos), 1.283 + generate_earlyret_entry_for(ltos), 1.284 + generate_earlyret_entry_for(ftos), 1.285 + generate_earlyret_entry_for(dtos), 1.286 + generate_earlyret_entry_for(vtos) 1.287 + ); 1.288 + } 1.289 + 1.290 + { CodeletMark cm(_masm, "deoptimization entry points"); 1.291 + for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) { 1.292 + Interpreter::_deopt_entry[i] = 1.293 + EntryPoint( 1.294 + generate_deopt_entry_for(itos, i), 1.295 + generate_deopt_entry_for(itos, i), 1.296 + generate_deopt_entry_for(itos, i), 1.297 + generate_deopt_entry_for(atos, i), 1.298 + generate_deopt_entry_for(itos, i), 1.299 + generate_deopt_entry_for(ltos, i), 1.300 + generate_deopt_entry_for(ftos, i), 1.301 + generate_deopt_entry_for(dtos, i), 1.302 + generate_deopt_entry_for(vtos, i) 1.303 + ); 1.304 + } 1.305 + } 1.306 + 1.307 + { CodeletMark cm(_masm, "result handlers for native calls"); 1.308 + // The various result converter stublets. 1.309 + int is_generated[Interpreter::number_of_result_handlers]; 1.310 + memset(is_generated, 0, sizeof(is_generated)); 1.311 + 1.312 + for (int i = 0; i < Interpreter::number_of_result_handlers; i++) { 1.313 + BasicType type = types[i]; 1.314 + if (!is_generated[Interpreter::BasicType_as_index(type)]++) { 1.315 + Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type); 1.316 + } 1.317 + } 1.318 + } 1.319 + 1.320 + { CodeletMark cm(_masm, "continuation entry points"); 1.321 + Interpreter::_continuation_entry = 1.322 + EntryPoint( 1.323 + generate_continuation_for(btos), 1.324 + generate_continuation_for(ctos), 1.325 + generate_continuation_for(stos), 1.326 + generate_continuation_for(atos), 1.327 + generate_continuation_for(itos), 1.328 + generate_continuation_for(ltos), 1.329 + generate_continuation_for(ftos), 1.330 + generate_continuation_for(dtos), 1.331 + generate_continuation_for(vtos) 1.332 + ); 1.333 + } 1.334 + 1.335 + { CodeletMark cm(_masm, "safepoint entry points"); 1.336 + Interpreter::_safept_entry = 1.337 + EntryPoint( 1.338 + generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), 1.339 + generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), 1.340 + generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), 1.341 + generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), 1.342 + generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), 1.343 + generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), 1.344 + generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), 1.345 + generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), 1.346 + generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)) 1.347 + ); 1.348 + } 1.349 + 1.350 + { CodeletMark cm(_masm, "exception handling"); 1.351 + // (Note: this is not safepoint safe because thread may return to compiled code) 1.352 + generate_throw_exception(); 1.353 + } 1.354 + 1.355 + { CodeletMark cm(_masm, "throw exception entrypoints"); 1.356 + Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException"); 1.357 + Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException" ); 1.358 + Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException" , "/ by zero"); 1.359 + Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler(); 1.360 + Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException" , NULL ); 1.361 + Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler(); 1.362 + } 1.363 + 1.364 + 1.365 + 1.366 +#define method_entry(kind) \ 1.367 + { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \ 1.368 + Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind); \ 1.369 + } 1.370 + 1.371 + // all non-native method kinds 1.372 + method_entry(zerolocals) 1.373 + method_entry(zerolocals_synchronized) 1.374 + method_entry(empty) 1.375 + method_entry(accessor) 1.376 + method_entry(abstract) 1.377 + method_entry(java_lang_math_sin ) 1.378 + method_entry(java_lang_math_cos ) 1.379 + method_entry(java_lang_math_tan ) 1.380 + method_entry(java_lang_math_abs ) 1.381 + method_entry(java_lang_math_sqrt ) 1.382 + method_entry(java_lang_math_log ) 1.383 + method_entry(java_lang_math_log10) 1.384 + method_entry(java_lang_math_exp ) 1.385 + method_entry(java_lang_math_pow ) 1.386 + method_entry(java_lang_ref_reference_get) 1.387 + 1.388 + if (UseCRC32Intrinsics) { 1.389 + method_entry(java_util_zip_CRC32_update) 1.390 + method_entry(java_util_zip_CRC32_updateBytes) 1.391 + method_entry(java_util_zip_CRC32_updateByteBuffer) 1.392 + } 1.393 + 1.394 + initialize_method_handle_entries(); 1.395 + 1.396 + // all native method kinds (must be one contiguous block) 1.397 + Interpreter::_native_entry_begin = Interpreter::code()->code_end(); 1.398 + method_entry(native) 1.399 + method_entry(native_synchronized) 1.400 + Interpreter::_native_entry_end = Interpreter::code()->code_end(); 1.401 + 1.402 +#undef method_entry 1.403 + 1.404 + // Bytecodes 1.405 + set_entry_points_for_all_bytes(); 1.406 + set_safepoints_for_all_bytes(); 1.407 +} 1.408 + 1.409 +//------------------------------------------------------------------------------------------------------------------------ 1.410 + 1.411 +address TemplateInterpreterGenerator::generate_error_exit(const char* msg) { 1.412 + address entry = __ pc(); 1.413 + __ stop(msg); 1.414 + return entry; 1.415 +} 1.416 + 1.417 + 1.418 +//------------------------------------------------------------------------------------------------------------------------ 1.419 + 1.420 +void TemplateInterpreterGenerator::set_entry_points_for_all_bytes() { 1.421 + for (int i = 0; i < DispatchTable::length; i++) { 1.422 + Bytecodes::Code code = (Bytecodes::Code)i; 1.423 + if (Bytecodes::is_defined(code)) { 1.424 + set_entry_points(code); 1.425 + } else { 1.426 + set_unimplemented(i); 1.427 + } 1.428 + } 1.429 +} 1.430 + 1.431 + 1.432 +void TemplateInterpreterGenerator::set_safepoints_for_all_bytes() { 1.433 + for (int i = 0; i < DispatchTable::length; i++) { 1.434 + Bytecodes::Code code = (Bytecodes::Code)i; 1.435 + if (Bytecodes::is_defined(code)) Interpreter::_safept_table.set_entry(code, Interpreter::_safept_entry); 1.436 + } 1.437 +} 1.438 + 1.439 + 1.440 +void TemplateInterpreterGenerator::set_unimplemented(int i) { 1.441 + address e = _unimplemented_bytecode; 1.442 + EntryPoint entry(e, e, e, e, e, e, e, e, e); 1.443 + Interpreter::_normal_table.set_entry(i, entry); 1.444 + Interpreter::_wentry_point[i] = _unimplemented_bytecode; 1.445 +} 1.446 + 1.447 + 1.448 +void TemplateInterpreterGenerator::set_entry_points(Bytecodes::Code code) { 1.449 + CodeletMark cm(_masm, Bytecodes::name(code), code); 1.450 + // initialize entry points 1.451 + assert(_unimplemented_bytecode != NULL, "should have been generated before"); 1.452 + assert(_illegal_bytecode_sequence != NULL, "should have been generated before"); 1.453 + address bep = _illegal_bytecode_sequence; 1.454 + address cep = _illegal_bytecode_sequence; 1.455 + address sep = _illegal_bytecode_sequence; 1.456 + address aep = _illegal_bytecode_sequence; 1.457 + address iep = _illegal_bytecode_sequence; 1.458 + address lep = _illegal_bytecode_sequence; 1.459 + address fep = _illegal_bytecode_sequence; 1.460 + address dep = _illegal_bytecode_sequence; 1.461 + address vep = _unimplemented_bytecode; 1.462 + address wep = _unimplemented_bytecode; 1.463 + // code for short & wide version of bytecode 1.464 + if (Bytecodes::is_defined(code)) { 1.465 + Template* t = TemplateTable::template_for(code); 1.466 + assert(t->is_valid(), "just checking"); 1.467 + set_short_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); 1.468 + } 1.469 + if (Bytecodes::wide_is_defined(code)) { 1.470 + Template* t = TemplateTable::template_for_wide(code); 1.471 + assert(t->is_valid(), "just checking"); 1.472 + set_wide_entry_point(t, wep); 1.473 + } 1.474 + // set entry points 1.475 + EntryPoint entry(bep, cep, sep, aep, iep, lep, fep, dep, vep); 1.476 + Interpreter::_normal_table.set_entry(code, entry); 1.477 + Interpreter::_wentry_point[code] = wep; 1.478 +} 1.479 + 1.480 + 1.481 +void TemplateInterpreterGenerator::set_wide_entry_point(Template* t, address& wep) { 1.482 + assert(t->is_valid(), "template must exist"); 1.483 + assert(t->tos_in() == vtos, "only vtos tos_in supported for wide instructions"); 1.484 + wep = __ pc(); generate_and_dispatch(t); 1.485 +} 1.486 + 1.487 + 1.488 +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) { 1.489 + assert(t->is_valid(), "template must exist"); 1.490 + switch (t->tos_in()) { 1.491 + case btos: 1.492 + case ctos: 1.493 + case stos: 1.494 + ShouldNotReachHere(); // btos/ctos/stos should use itos. 1.495 + break; 1.496 + case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break; 1.497 + case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break; 1.498 + case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break; 1.499 + case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break; 1.500 + case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break; 1.501 + case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); break; 1.502 + default : ShouldNotReachHere(); break; 1.503 + } 1.504 +} 1.505 + 1.506 + 1.507 +//------------------------------------------------------------------------------------------------------------------------ 1.508 + 1.509 +void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) { 1.510 + if (PrintBytecodeHistogram) histogram_bytecode(t); 1.511 +#ifndef PRODUCT 1.512 + // debugging code 1.513 + if (CountBytecodes || TraceBytecodes || StopInterpreterAt > 0) count_bytecode(); 1.514 + if (PrintBytecodePairHistogram) histogram_bytecode_pair(t); 1.515 + if (TraceBytecodes) trace_bytecode(t); 1.516 + if (StopInterpreterAt > 0) stop_interpreter_at(); 1.517 + __ verify_FPU(1, t->tos_in()); 1.518 +#endif // !PRODUCT 1.519 + int step; 1.520 + if (!t->does_dispatch()) { 1.521 + step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode()); 1.522 + if (tos_out == ilgl) tos_out = t->tos_out(); 1.523 + // compute bytecode size 1.524 + assert(step > 0, "just checkin'"); 1.525 + // setup stuff for dispatching next bytecode 1.526 + if (ProfileInterpreter && VerifyDataPointer 1.527 + && MethodData::bytecode_has_profile(t->bytecode())) { 1.528 + __ verify_method_data_pointer(); 1.529 + } 1.530 + __ dispatch_prolog(tos_out, step); 1.531 + } 1.532 + // generate template 1.533 + t->generate(_masm); 1.534 + // advance 1.535 + if (t->does_dispatch()) { 1.536 +#ifdef ASSERT 1.537 + // make sure execution doesn't go beyond this point if code is broken 1.538 + __ should_not_reach_here(); 1.539 +#endif // ASSERT 1.540 + } else { 1.541 + // dispatch to next bytecode 1.542 + __ dispatch_epilog(tos_out, step); 1.543 + } 1.544 +} 1.545 + 1.546 +//------------------------------------------------------------------------------------------------------------------------ 1.547 +// Entry points 1.548 + 1.549 +/** 1.550 + * Returns the return entry table for the given invoke bytecode. 1.551 + */ 1.552 +address* TemplateInterpreter::invoke_return_entry_table_for(Bytecodes::Code code) { 1.553 + switch (code) { 1.554 + case Bytecodes::_invokestatic: 1.555 + case Bytecodes::_invokespecial: 1.556 + case Bytecodes::_invokevirtual: 1.557 + case Bytecodes::_invokehandle: 1.558 + return Interpreter::invoke_return_entry_table(); 1.559 + case Bytecodes::_invokeinterface: 1.560 + return Interpreter::invokeinterface_return_entry_table(); 1.561 + case Bytecodes::_invokedynamic: 1.562 + return Interpreter::invokedynamic_return_entry_table(); 1.563 + default: 1.564 + fatal(err_msg("invalid bytecode: %s", Bytecodes::name(code))); 1.565 + return NULL; 1.566 + } 1.567 +} 1.568 + 1.569 +/** 1.570 + * Returns the return entry address for the given top-of-stack state and bytecode. 1.571 + */ 1.572 +address TemplateInterpreter::return_entry(TosState state, int length, Bytecodes::Code code) { 1.573 + guarantee(0 <= length && length < Interpreter::number_of_return_entries, "illegal length"); 1.574 + const int index = TosState_as_index(state); 1.575 + switch (code) { 1.576 + case Bytecodes::_invokestatic: 1.577 + case Bytecodes::_invokespecial: 1.578 + case Bytecodes::_invokevirtual: 1.579 + case Bytecodes::_invokehandle: 1.580 + return _invoke_return_entry[index]; 1.581 + case Bytecodes::_invokeinterface: 1.582 + return _invokeinterface_return_entry[index]; 1.583 + case Bytecodes::_invokedynamic: 1.584 + return _invokedynamic_return_entry[index]; 1.585 + default: 1.586 + assert(!Bytecodes::is_invoke(code), err_msg("invoke instructions should be handled separately: %s", Bytecodes::name(code))); 1.587 + return _return_entry[length].entry(state); 1.588 + } 1.589 +} 1.590 + 1.591 + 1.592 +address TemplateInterpreter::deopt_entry(TosState state, int length) { 1.593 + guarantee(0 <= length && length < Interpreter::number_of_deopt_entries, "illegal length"); 1.594 + return _deopt_entry[length].entry(state); 1.595 +} 1.596 + 1.597 +//------------------------------------------------------------------------------------------------------------------------ 1.598 +// Suport for invokes 1.599 + 1.600 +int TemplateInterpreter::TosState_as_index(TosState state) { 1.601 + assert( state < number_of_states , "Invalid state in TosState_as_index"); 1.602 + assert(0 <= (int)state && (int)state < TemplateInterpreter::number_of_return_addrs, "index out of bounds"); 1.603 + return (int)state; 1.604 +} 1.605 + 1.606 + 1.607 +//------------------------------------------------------------------------------------------------------------------------ 1.608 +// Safepoint suppport 1.609 + 1.610 +static inline void copy_table(address* from, address* to, int size) { 1.611 + // Copy non-overlapping tables. The copy has to occur word wise for MT safety. 1.612 + while (size-- > 0) *to++ = *from++; 1.613 +} 1.614 + 1.615 +void TemplateInterpreter::notice_safepoints() { 1.616 + if (!_notice_safepoints) { 1.617 + // switch to safepoint dispatch table 1.618 + _notice_safepoints = true; 1.619 + copy_table((address*)&_safept_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address)); 1.620 + } 1.621 +} 1.622 + 1.623 +// switch from the dispatch table which notices safepoints back to the 1.624 +// normal dispatch table. So that we can notice single stepping points, 1.625 +// keep the safepoint dispatch table if we are single stepping in JVMTI. 1.626 +// Note that the should_post_single_step test is exactly as fast as the 1.627 +// JvmtiExport::_enabled test and covers both cases. 1.628 +void TemplateInterpreter::ignore_safepoints() { 1.629 + if (_notice_safepoints) { 1.630 + if (!JvmtiExport::should_post_single_step()) { 1.631 + // switch to normal dispatch table 1.632 + _notice_safepoints = false; 1.633 + copy_table((address*)&_normal_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address)); 1.634 + } 1.635 + } 1.636 +} 1.637 + 1.638 +//------------------------------------------------------------------------------------------------------------------------ 1.639 +// Deoptimization support 1.640 + 1.641 +// If deoptimization happens, this function returns the point of next bytecode to continue execution 1.642 +address TemplateInterpreter::deopt_continue_after_entry(Method* method, address bcp, int callee_parameters, bool is_top_frame) { 1.643 + return AbstractInterpreter::deopt_continue_after_entry(method, bcp, callee_parameters, is_top_frame); 1.644 +} 1.645 + 1.646 +// If deoptimization happens, this function returns the point where the interpreter reexecutes 1.647 +// the bytecode. 1.648 +// Note: Bytecodes::_athrow (C1 only) and Bytecodes::_return are the special cases 1.649 +// that do not return "Interpreter::deopt_entry(vtos, 0)" 1.650 +address TemplateInterpreter::deopt_reexecute_entry(Method* method, address bcp) { 1.651 + assert(method->contains(bcp), "just checkin'"); 1.652 + Bytecodes::Code code = Bytecodes::java_code_at(method, bcp); 1.653 + if (code == Bytecodes::_return) { 1.654 + // This is used for deopt during registration of finalizers 1.655 + // during Object.<init>. We simply need to resume execution at 1.656 + // the standard return vtos bytecode to pop the frame normally. 1.657 + // reexecuting the real bytecode would cause double registration 1.658 + // of the finalizable object. 1.659 + return _normal_table.entry(Bytecodes::_return).entry(vtos); 1.660 + } else { 1.661 + return AbstractInterpreter::deopt_reexecute_entry(method, bcp); 1.662 + } 1.663 +} 1.664 + 1.665 +// If deoptimization happens, the interpreter should reexecute this bytecode. 1.666 +// This function mainly helps the compilers to set up the reexecute bit. 1.667 +bool TemplateInterpreter::bytecode_should_reexecute(Bytecodes::Code code) { 1.668 + if (code == Bytecodes::_return) { 1.669 + //Yes, we consider Bytecodes::_return as a special case of reexecution 1.670 + return true; 1.671 + } else { 1.672 + return AbstractInterpreter::bytecode_should_reexecute(code); 1.673 + } 1.674 +} 1.675 + 1.676 +#endif // !CC_INTERP