Wed, 03 Jul 2019 20:42:37 +0800
Merge
aoqi@0 | 1 | /* |
kevinw@8368 | 2 | * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. |
aoqi@0 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
aoqi@0 | 4 | * |
aoqi@0 | 5 | * This code is free software; you can redistribute it and/or modify it |
aoqi@0 | 6 | * under the terms of the GNU General Public License version 2 only, as |
aoqi@0 | 7 | * published by the Free Software Foundation. |
aoqi@0 | 8 | * |
aoqi@0 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
aoqi@0 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
aoqi@0 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
aoqi@0 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
aoqi@0 | 13 | * accompanied this code). |
aoqi@0 | 14 | * |
aoqi@0 | 15 | * You should have received a copy of the GNU General Public License version |
aoqi@0 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
aoqi@0 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
aoqi@0 | 18 | * |
aoqi@0 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
aoqi@0 | 20 | * or visit www.oracle.com if you need additional information or have any |
aoqi@0 | 21 | * questions. |
aoqi@0 | 22 | * |
aoqi@0 | 23 | */ |
aoqi@0 | 24 | |
aoqi@0 | 25 | #include "precompiled.hpp" |
aoqi@0 | 26 | #include "interpreter/interpreter.hpp" |
aoqi@0 | 27 | #include "interpreter/interpreterGenerator.hpp" |
aoqi@0 | 28 | #include "interpreter/interpreterRuntime.hpp" |
aoqi@0 | 29 | #include "interpreter/templateTable.hpp" |
aoqi@0 | 30 | |
aoqi@0 | 31 | #ifndef CC_INTERP |
aoqi@0 | 32 | |
aoqi@0 | 33 | # define __ _masm-> |
aoqi@0 | 34 | |
aoqi@0 | 35 | void TemplateInterpreter::initialize() { |
aoqi@0 | 36 | if (_code != NULL) return; |
aoqi@0 | 37 | // assertions |
aoqi@0 | 38 | assert((int)Bytecodes::number_of_codes <= (int)DispatchTable::length, |
aoqi@0 | 39 | "dispatch table too small"); |
aoqi@0 | 40 | |
aoqi@0 | 41 | AbstractInterpreter::initialize(); |
aoqi@0 | 42 | |
aoqi@0 | 43 | TemplateTable::initialize(); |
aoqi@0 | 44 | |
aoqi@0 | 45 | // generate interpreter |
aoqi@0 | 46 | { ResourceMark rm; |
aoqi@0 | 47 | TraceTime timer("Interpreter generation", TraceStartupTime); |
aoqi@0 | 48 | int code_size = InterpreterCodeSize; |
aoqi@0 | 49 | NOT_PRODUCT(code_size *= 4;) // debug uses extra interpreter code space |
aoqi@0 | 50 | _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL, |
aoqi@0 | 51 | "Interpreter"); |
aoqi@0 | 52 | InterpreterGenerator g(_code); |
aoqi@0 | 53 | if (PrintInterpreter) print(); |
aoqi@0 | 54 | } |
aoqi@0 | 55 | |
aoqi@0 | 56 | // initialize dispatch table |
aoqi@0 | 57 | _active_table = _normal_table; |
aoqi@0 | 58 | } |
aoqi@0 | 59 | |
aoqi@0 | 60 | //------------------------------------------------------------------------------------------------------------------------ |
aoqi@0 | 61 | // Implementation of EntryPoint |
aoqi@0 | 62 | |
aoqi@0 | 63 | EntryPoint::EntryPoint() { |
kevinw@8368 | 64 | assert(number_of_states == 10, "check the code below"); |
aoqi@0 | 65 | _entry[btos] = NULL; |
kevinw@8368 | 66 | _entry[ztos] = NULL; |
aoqi@0 | 67 | _entry[ctos] = NULL; |
aoqi@0 | 68 | _entry[stos] = NULL; |
aoqi@0 | 69 | _entry[atos] = NULL; |
aoqi@0 | 70 | _entry[itos] = NULL; |
aoqi@0 | 71 | _entry[ltos] = NULL; |
aoqi@0 | 72 | _entry[ftos] = NULL; |
aoqi@0 | 73 | _entry[dtos] = NULL; |
aoqi@0 | 74 | _entry[vtos] = NULL; |
aoqi@0 | 75 | } |
aoqi@0 | 76 | |
aoqi@0 | 77 | |
kevinw@8368 | 78 | EntryPoint::EntryPoint(address bentry, address zentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) { |
kevinw@8368 | 79 | assert(number_of_states == 10, "check the code below"); |
aoqi@0 | 80 | _entry[btos] = bentry; |
kevinw@8368 | 81 | _entry[ztos] = zentry; |
aoqi@0 | 82 | _entry[ctos] = centry; |
aoqi@0 | 83 | _entry[stos] = sentry; |
aoqi@0 | 84 | _entry[atos] = aentry; |
aoqi@0 | 85 | _entry[itos] = ientry; |
aoqi@0 | 86 | _entry[ltos] = lentry; |
aoqi@0 | 87 | _entry[ftos] = fentry; |
aoqi@0 | 88 | _entry[dtos] = dentry; |
aoqi@0 | 89 | _entry[vtos] = ventry; |
aoqi@0 | 90 | } |
aoqi@0 | 91 | |
aoqi@0 | 92 | |
aoqi@0 | 93 | void EntryPoint::set_entry(TosState state, address entry) { |
aoqi@0 | 94 | assert(0 <= state && state < number_of_states, "state out of bounds"); |
aoqi@0 | 95 | _entry[state] = entry; |
aoqi@0 | 96 | } |
aoqi@0 | 97 | |
aoqi@0 | 98 | |
aoqi@0 | 99 | address EntryPoint::entry(TosState state) const { |
aoqi@0 | 100 | assert(0 <= state && state < number_of_states, "state out of bounds"); |
aoqi@0 | 101 | return _entry[state]; |
aoqi@0 | 102 | } |
aoqi@0 | 103 | |
aoqi@0 | 104 | |
aoqi@0 | 105 | void EntryPoint::print() { |
aoqi@0 | 106 | tty->print("["); |
aoqi@0 | 107 | for (int i = 0; i < number_of_states; i++) { |
aoqi@0 | 108 | if (i > 0) tty->print(", "); |
aoqi@0 | 109 | tty->print(INTPTR_FORMAT, p2i(_entry[i])); |
aoqi@0 | 110 | } |
aoqi@0 | 111 | tty->print("]"); |
aoqi@0 | 112 | } |
aoqi@0 | 113 | |
aoqi@0 | 114 | |
aoqi@0 | 115 | bool EntryPoint::operator == (const EntryPoint& y) { |
aoqi@0 | 116 | int i = number_of_states; |
aoqi@0 | 117 | while (i-- > 0) { |
aoqi@0 | 118 | if (_entry[i] != y._entry[i]) return false; |
aoqi@0 | 119 | } |
aoqi@0 | 120 | return true; |
aoqi@0 | 121 | } |
aoqi@0 | 122 | |
aoqi@0 | 123 | |
aoqi@0 | 124 | //------------------------------------------------------------------------------------------------------------------------ |
aoqi@0 | 125 | // Implementation of DispatchTable |
aoqi@0 | 126 | |
aoqi@0 | 127 | EntryPoint DispatchTable::entry(int i) const { |
aoqi@0 | 128 | assert(0 <= i && i < length, "index out of bounds"); |
aoqi@0 | 129 | return |
aoqi@0 | 130 | EntryPoint( |
aoqi@0 | 131 | _table[btos][i], |
kevinw@8368 | 132 | _table[ztos][i], |
aoqi@0 | 133 | _table[ctos][i], |
aoqi@0 | 134 | _table[stos][i], |
aoqi@0 | 135 | _table[atos][i], |
aoqi@0 | 136 | _table[itos][i], |
aoqi@0 | 137 | _table[ltos][i], |
aoqi@0 | 138 | _table[ftos][i], |
aoqi@0 | 139 | _table[dtos][i], |
aoqi@0 | 140 | _table[vtos][i] |
aoqi@0 | 141 | ); |
aoqi@0 | 142 | } |
aoqi@0 | 143 | |
aoqi@0 | 144 | |
aoqi@0 | 145 | void DispatchTable::set_entry(int i, EntryPoint& entry) { |
aoqi@0 | 146 | assert(0 <= i && i < length, "index out of bounds"); |
kevinw@8368 | 147 | assert(number_of_states == 10, "check the code below"); |
aoqi@0 | 148 | _table[btos][i] = entry.entry(btos); |
kevinw@8368 | 149 | _table[ztos][i] = entry.entry(ztos); |
aoqi@0 | 150 | _table[ctos][i] = entry.entry(ctos); |
aoqi@0 | 151 | _table[stos][i] = entry.entry(stos); |
aoqi@0 | 152 | _table[atos][i] = entry.entry(atos); |
aoqi@0 | 153 | _table[itos][i] = entry.entry(itos); |
aoqi@0 | 154 | _table[ltos][i] = entry.entry(ltos); |
aoqi@0 | 155 | _table[ftos][i] = entry.entry(ftos); |
aoqi@0 | 156 | _table[dtos][i] = entry.entry(dtos); |
aoqi@0 | 157 | _table[vtos][i] = entry.entry(vtos); |
aoqi@0 | 158 | } |
aoqi@0 | 159 | |
aoqi@0 | 160 | |
aoqi@0 | 161 | bool DispatchTable::operator == (DispatchTable& y) { |
aoqi@0 | 162 | int i = length; |
aoqi@0 | 163 | while (i-- > 0) { |
aoqi@0 | 164 | EntryPoint t = y.entry(i); // for compiler compatibility (BugId 4150096) |
aoqi@0 | 165 | if (!(entry(i) == t)) return false; |
aoqi@0 | 166 | } |
aoqi@0 | 167 | return true; |
aoqi@0 | 168 | } |
aoqi@0 | 169 | |
aoqi@0 | 170 | address TemplateInterpreter::_remove_activation_entry = NULL; |
aoqi@0 | 171 | address TemplateInterpreter::_remove_activation_preserving_args_entry = NULL; |
aoqi@0 | 172 | |
aoqi@0 | 173 | |
aoqi@0 | 174 | address TemplateInterpreter::_throw_ArrayIndexOutOfBoundsException_entry = NULL; |
aoqi@0 | 175 | address TemplateInterpreter::_throw_ArrayStoreException_entry = NULL; |
aoqi@0 | 176 | address TemplateInterpreter::_throw_ArithmeticException_entry = NULL; |
aoqi@0 | 177 | address TemplateInterpreter::_throw_ClassCastException_entry = NULL; |
aoqi@0 | 178 | address TemplateInterpreter::_throw_NullPointerException_entry = NULL; |
aoqi@0 | 179 | address TemplateInterpreter::_throw_StackOverflowError_entry = NULL; |
aoqi@0 | 180 | address TemplateInterpreter::_throw_exception_entry = NULL; |
aoqi@0 | 181 | |
aoqi@0 | 182 | #ifndef PRODUCT |
aoqi@0 | 183 | EntryPoint TemplateInterpreter::_trace_code; |
aoqi@0 | 184 | #endif // !PRODUCT |
aoqi@0 | 185 | EntryPoint TemplateInterpreter::_return_entry[TemplateInterpreter::number_of_return_entries]; |
aoqi@0 | 186 | EntryPoint TemplateInterpreter::_earlyret_entry; |
aoqi@0 | 187 | EntryPoint TemplateInterpreter::_deopt_entry [TemplateInterpreter::number_of_deopt_entries ]; |
aoqi@0 | 188 | EntryPoint TemplateInterpreter::_continuation_entry; |
aoqi@0 | 189 | EntryPoint TemplateInterpreter::_safept_entry; |
aoqi@0 | 190 | |
aoqi@0 | 191 | address TemplateInterpreter::_invoke_return_entry[TemplateInterpreter::number_of_return_addrs]; |
aoqi@0 | 192 | address TemplateInterpreter::_invokeinterface_return_entry[TemplateInterpreter::number_of_return_addrs]; |
aoqi@0 | 193 | address TemplateInterpreter::_invokedynamic_return_entry[TemplateInterpreter::number_of_return_addrs]; |
aoqi@0 | 194 | |
aoqi@0 | 195 | DispatchTable TemplateInterpreter::_active_table; |
aoqi@0 | 196 | DispatchTable TemplateInterpreter::_normal_table; |
aoqi@0 | 197 | DispatchTable TemplateInterpreter::_safept_table; |
aoqi@0 | 198 | address TemplateInterpreter::_wentry_point[DispatchTable::length]; |
aoqi@0 | 199 | |
aoqi@0 | 200 | TemplateInterpreterGenerator::TemplateInterpreterGenerator(StubQueue* _code): AbstractInterpreterGenerator(_code) { |
aoqi@0 | 201 | _unimplemented_bytecode = NULL; |
aoqi@0 | 202 | _illegal_bytecode_sequence = NULL; |
aoqi@0 | 203 | } |
aoqi@0 | 204 | |
aoqi@0 | 205 | static const BasicType types[Interpreter::number_of_result_handlers] = { |
aoqi@0 | 206 | T_BOOLEAN, |
aoqi@0 | 207 | T_CHAR , |
aoqi@0 | 208 | T_BYTE , |
aoqi@0 | 209 | T_SHORT , |
aoqi@0 | 210 | T_INT , |
aoqi@0 | 211 | T_LONG , |
aoqi@0 | 212 | T_VOID , |
aoqi@0 | 213 | T_FLOAT , |
aoqi@0 | 214 | T_DOUBLE , |
aoqi@0 | 215 | T_OBJECT |
aoqi@0 | 216 | }; |
aoqi@0 | 217 | |
aoqi@0 | 218 | void TemplateInterpreterGenerator::generate_all() { |
aoqi@0 | 219 | AbstractInterpreterGenerator::generate_all(); |
aoqi@0 | 220 | |
aoqi@0 | 221 | { CodeletMark cm(_masm, "error exits"); |
aoqi@0 | 222 | _unimplemented_bytecode = generate_error_exit("unimplemented bytecode"); |
aoqi@0 | 223 | _illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified"); |
aoqi@0 | 224 | } |
aoqi@0 | 225 | |
aoqi@0 | 226 | #ifndef PRODUCT |
aoqi@0 | 227 | if (TraceBytecodes) { |
aoqi@0 | 228 | CodeletMark cm(_masm, "bytecode tracing support"); |
aoqi@0 | 229 | Interpreter::_trace_code = |
aoqi@0 | 230 | EntryPoint( |
aoqi@0 | 231 | generate_trace_code(btos), |
kevinw@8368 | 232 | generate_trace_code(ztos), |
aoqi@0 | 233 | generate_trace_code(ctos), |
aoqi@0 | 234 | generate_trace_code(stos), |
aoqi@0 | 235 | generate_trace_code(atos), |
aoqi@0 | 236 | generate_trace_code(itos), |
aoqi@0 | 237 | generate_trace_code(ltos), |
aoqi@0 | 238 | generate_trace_code(ftos), |
aoqi@0 | 239 | generate_trace_code(dtos), |
aoqi@0 | 240 | generate_trace_code(vtos) |
aoqi@0 | 241 | ); |
aoqi@0 | 242 | } |
aoqi@0 | 243 | #endif // !PRODUCT |
aoqi@0 | 244 | |
aoqi@0 | 245 | { CodeletMark cm(_masm, "return entry points"); |
aoqi@0 | 246 | const int index_size = sizeof(u2); |
aoqi@0 | 247 | for (int i = 0; i < Interpreter::number_of_return_entries; i++) { |
aoqi@0 | 248 | Interpreter::_return_entry[i] = |
aoqi@0 | 249 | EntryPoint( |
aoqi@0 | 250 | generate_return_entry_for(itos, i, index_size), |
aoqi@0 | 251 | generate_return_entry_for(itos, i, index_size), |
aoqi@0 | 252 | generate_return_entry_for(itos, i, index_size), |
kevinw@8368 | 253 | generate_return_entry_for(itos, i, index_size), |
aoqi@0 | 254 | generate_return_entry_for(atos, i, index_size), |
aoqi@0 | 255 | generate_return_entry_for(itos, i, index_size), |
aoqi@0 | 256 | generate_return_entry_for(ltos, i, index_size), |
aoqi@0 | 257 | generate_return_entry_for(ftos, i, index_size), |
aoqi@0 | 258 | generate_return_entry_for(dtos, i, index_size), |
aoqi@0 | 259 | generate_return_entry_for(vtos, i, index_size) |
aoqi@0 | 260 | ); |
aoqi@0 | 261 | } |
aoqi@0 | 262 | } |
aoqi@0 | 263 | |
aoqi@0 | 264 | { CodeletMark cm(_masm, "invoke return entry points"); |
kevinw@8368 | 265 | // These states are in order specified in TosState, except btos/ztos/ctos/stos are |
kevinw@8368 | 266 | // really the same as itos since there is no top of stack optimization for these types |
kevinw@8368 | 267 | const TosState states[] = {itos, itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos, ilgl}; |
aoqi@0 | 268 | const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic); |
aoqi@0 | 269 | const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface); |
aoqi@0 | 270 | const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic); |
aoqi@0 | 271 | |
aoqi@0 | 272 | for (int i = 0; i < Interpreter::number_of_return_addrs; i++) { |
aoqi@0 | 273 | TosState state = states[i]; |
kevinw@8368 | 274 | assert(state != ilgl, "states array is wrong above"); |
aoqi@0 | 275 | Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2)); |
aoqi@0 | 276 | Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2)); |
aoqi@0 | 277 | Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4)); |
aoqi@0 | 278 | } |
aoqi@0 | 279 | } |
aoqi@0 | 280 | |
aoqi@0 | 281 | { CodeletMark cm(_masm, "earlyret entry points"); |
aoqi@0 | 282 | Interpreter::_earlyret_entry = |
aoqi@0 | 283 | EntryPoint( |
aoqi@0 | 284 | generate_earlyret_entry_for(btos), |
kevinw@8368 | 285 | generate_earlyret_entry_for(ztos), |
aoqi@0 | 286 | generate_earlyret_entry_for(ctos), |
aoqi@0 | 287 | generate_earlyret_entry_for(stos), |
aoqi@0 | 288 | generate_earlyret_entry_for(atos), |
aoqi@0 | 289 | generate_earlyret_entry_for(itos), |
aoqi@0 | 290 | generate_earlyret_entry_for(ltos), |
aoqi@0 | 291 | generate_earlyret_entry_for(ftos), |
aoqi@0 | 292 | generate_earlyret_entry_for(dtos), |
aoqi@0 | 293 | generate_earlyret_entry_for(vtos) |
aoqi@0 | 294 | ); |
aoqi@0 | 295 | } |
aoqi@0 | 296 | |
aoqi@0 | 297 | { CodeletMark cm(_masm, "deoptimization entry points"); |
aoqi@0 | 298 | for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) { |
aoqi@0 | 299 | Interpreter::_deopt_entry[i] = |
aoqi@0 | 300 | EntryPoint( |
aoqi@0 | 301 | generate_deopt_entry_for(itos, i), |
aoqi@0 | 302 | generate_deopt_entry_for(itos, i), |
aoqi@0 | 303 | generate_deopt_entry_for(itos, i), |
kevinw@8368 | 304 | generate_deopt_entry_for(itos, i), |
aoqi@0 | 305 | generate_deopt_entry_for(atos, i), |
aoqi@0 | 306 | generate_deopt_entry_for(itos, i), |
aoqi@0 | 307 | generate_deopt_entry_for(ltos, i), |
aoqi@0 | 308 | generate_deopt_entry_for(ftos, i), |
aoqi@0 | 309 | generate_deopt_entry_for(dtos, i), |
aoqi@0 | 310 | generate_deopt_entry_for(vtos, i) |
aoqi@0 | 311 | ); |
aoqi@0 | 312 | } |
aoqi@0 | 313 | } |
aoqi@0 | 314 | |
aoqi@0 | 315 | { CodeletMark cm(_masm, "result handlers for native calls"); |
aoqi@0 | 316 | // The various result converter stublets. |
aoqi@0 | 317 | int is_generated[Interpreter::number_of_result_handlers]; |
aoqi@0 | 318 | memset(is_generated, 0, sizeof(is_generated)); |
aoqi@0 | 319 | |
aoqi@0 | 320 | for (int i = 0; i < Interpreter::number_of_result_handlers; i++) { |
aoqi@0 | 321 | BasicType type = types[i]; |
aoqi@0 | 322 | if (!is_generated[Interpreter::BasicType_as_index(type)]++) { |
aoqi@0 | 323 | Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type); |
aoqi@0 | 324 | } |
aoqi@0 | 325 | } |
aoqi@0 | 326 | } |
aoqi@0 | 327 | |
aoqi@0 | 328 | { CodeletMark cm(_masm, "continuation entry points"); |
aoqi@0 | 329 | Interpreter::_continuation_entry = |
aoqi@0 | 330 | EntryPoint( |
aoqi@0 | 331 | generate_continuation_for(btos), |
kevinw@8368 | 332 | generate_continuation_for(ztos), |
aoqi@0 | 333 | generate_continuation_for(ctos), |
aoqi@0 | 334 | generate_continuation_for(stos), |
aoqi@0 | 335 | generate_continuation_for(atos), |
aoqi@0 | 336 | generate_continuation_for(itos), |
aoqi@0 | 337 | generate_continuation_for(ltos), |
aoqi@0 | 338 | generate_continuation_for(ftos), |
aoqi@0 | 339 | generate_continuation_for(dtos), |
aoqi@0 | 340 | generate_continuation_for(vtos) |
aoqi@0 | 341 | ); |
aoqi@0 | 342 | } |
aoqi@0 | 343 | |
aoqi@0 | 344 | { CodeletMark cm(_masm, "safepoint entry points"); |
aoqi@0 | 345 | Interpreter::_safept_entry = |
aoqi@0 | 346 | EntryPoint( |
aoqi@0 | 347 | generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
kevinw@8368 | 348 | generate_safept_entry_for(ztos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
aoqi@0 | 349 | generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
aoqi@0 | 350 | generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
aoqi@0 | 351 | generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
aoqi@0 | 352 | generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
aoqi@0 | 353 | generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
aoqi@0 | 354 | generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
aoqi@0 | 355 | generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
aoqi@0 | 356 | generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)) |
aoqi@0 | 357 | ); |
aoqi@0 | 358 | } |
aoqi@0 | 359 | |
aoqi@0 | 360 | { CodeletMark cm(_masm, "exception handling"); |
aoqi@0 | 361 | // (Note: this is not safepoint safe because thread may return to compiled code) |
aoqi@0 | 362 | generate_throw_exception(); |
aoqi@0 | 363 | } |
aoqi@0 | 364 | |
aoqi@0 | 365 | { CodeletMark cm(_masm, "throw exception entrypoints"); |
aoqi@0 | 366 | Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException"); |
aoqi@0 | 367 | Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException" ); |
aoqi@0 | 368 | Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException" , "/ by zero"); |
aoqi@0 | 369 | Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler(); |
aoqi@0 | 370 | Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException" , NULL ); |
aoqi@0 | 371 | Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler(); |
aoqi@0 | 372 | } |
aoqi@0 | 373 | |
aoqi@0 | 374 | |
aoqi@0 | 375 | |
aoqi@0 | 376 | #define method_entry(kind) \ |
aoqi@0 | 377 | { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \ |
aoqi@0 | 378 | Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind); \ |
aoqi@0 | 379 | } |
aoqi@0 | 380 | |
aoqi@0 | 381 | // all non-native method kinds |
aoqi@0 | 382 | method_entry(zerolocals) |
aoqi@0 | 383 | method_entry(zerolocals_synchronized) |
aoqi@0 | 384 | method_entry(empty) |
aoqi@0 | 385 | method_entry(accessor) |
aoqi@0 | 386 | method_entry(abstract) |
aoqi@0 | 387 | method_entry(java_lang_math_sin ) |
aoqi@0 | 388 | method_entry(java_lang_math_cos ) |
aoqi@0 | 389 | method_entry(java_lang_math_tan ) |
aoqi@0 | 390 | method_entry(java_lang_math_abs ) |
aoqi@0 | 391 | method_entry(java_lang_math_sqrt ) |
aoqi@0 | 392 | method_entry(java_lang_math_log ) |
aoqi@0 | 393 | method_entry(java_lang_math_log10) |
aoqi@0 | 394 | method_entry(java_lang_math_exp ) |
aoqi@0 | 395 | method_entry(java_lang_math_pow ) |
aoqi@0 | 396 | method_entry(java_lang_ref_reference_get) |
aoqi@0 | 397 | |
aoqi@0 | 398 | if (UseCRC32Intrinsics) { |
aoqi@0 | 399 | method_entry(java_util_zip_CRC32_update) |
aoqi@0 | 400 | method_entry(java_util_zip_CRC32_updateBytes) |
aoqi@0 | 401 | method_entry(java_util_zip_CRC32_updateByteBuffer) |
aoqi@0 | 402 | } |
aoqi@0 | 403 | |
aoqi@0 | 404 | initialize_method_handle_entries(); |
aoqi@0 | 405 | |
aoqi@0 | 406 | // all native method kinds (must be one contiguous block) |
aoqi@0 | 407 | Interpreter::_native_entry_begin = Interpreter::code()->code_end(); |
aoqi@0 | 408 | method_entry(native) |
aoqi@0 | 409 | method_entry(native_synchronized) |
aoqi@0 | 410 | Interpreter::_native_entry_end = Interpreter::code()->code_end(); |
aoqi@0 | 411 | |
aoqi@0 | 412 | #undef method_entry |
aoqi@0 | 413 | |
aoqi@0 | 414 | // Bytecodes |
aoqi@0 | 415 | set_entry_points_for_all_bytes(); |
aoqi@0 | 416 | set_safepoints_for_all_bytes(); |
aoqi@0 | 417 | } |
aoqi@0 | 418 | |
aoqi@0 | 419 | //------------------------------------------------------------------------------------------------------------------------ |
aoqi@0 | 420 | |
aoqi@0 | 421 | address TemplateInterpreterGenerator::generate_error_exit(const char* msg) { |
aoqi@0 | 422 | address entry = __ pc(); |
aoqi@0 | 423 | __ stop(msg); |
aoqi@0 | 424 | return entry; |
aoqi@0 | 425 | } |
aoqi@0 | 426 | |
aoqi@0 | 427 | |
aoqi@0 | 428 | //------------------------------------------------------------------------------------------------------------------------ |
aoqi@0 | 429 | |
aoqi@0 | 430 | void TemplateInterpreterGenerator::set_entry_points_for_all_bytes() { |
aoqi@0 | 431 | for (int i = 0; i < DispatchTable::length; i++) { |
aoqi@0 | 432 | Bytecodes::Code code = (Bytecodes::Code)i; |
aoqi@0 | 433 | if (Bytecodes::is_defined(code)) { |
aoqi@0 | 434 | set_entry_points(code); |
aoqi@0 | 435 | } else { |
aoqi@0 | 436 | set_unimplemented(i); |
aoqi@0 | 437 | } |
aoqi@0 | 438 | } |
aoqi@0 | 439 | } |
aoqi@0 | 440 | |
aoqi@0 | 441 | |
aoqi@0 | 442 | void TemplateInterpreterGenerator::set_safepoints_for_all_bytes() { |
aoqi@0 | 443 | for (int i = 0; i < DispatchTable::length; i++) { |
aoqi@0 | 444 | Bytecodes::Code code = (Bytecodes::Code)i; |
aoqi@0 | 445 | if (Bytecodes::is_defined(code)) Interpreter::_safept_table.set_entry(code, Interpreter::_safept_entry); |
aoqi@0 | 446 | } |
aoqi@0 | 447 | } |
aoqi@0 | 448 | |
aoqi@0 | 449 | |
aoqi@0 | 450 | void TemplateInterpreterGenerator::set_unimplemented(int i) { |
aoqi@0 | 451 | address e = _unimplemented_bytecode; |
kevinw@8368 | 452 | EntryPoint entry(e, e, e, e, e, e, e, e, e, e); |
aoqi@0 | 453 | Interpreter::_normal_table.set_entry(i, entry); |
aoqi@0 | 454 | Interpreter::_wentry_point[i] = _unimplemented_bytecode; |
aoqi@0 | 455 | } |
aoqi@0 | 456 | |
aoqi@0 | 457 | |
aoqi@0 | 458 | void TemplateInterpreterGenerator::set_entry_points(Bytecodes::Code code) { |
aoqi@0 | 459 | CodeletMark cm(_masm, Bytecodes::name(code), code); |
aoqi@0 | 460 | // initialize entry points |
aoqi@0 | 461 | assert(_unimplemented_bytecode != NULL, "should have been generated before"); |
aoqi@0 | 462 | assert(_illegal_bytecode_sequence != NULL, "should have been generated before"); |
aoqi@0 | 463 | address bep = _illegal_bytecode_sequence; |
kevinw@8368 | 464 | address zep = _illegal_bytecode_sequence; |
aoqi@0 | 465 | address cep = _illegal_bytecode_sequence; |
aoqi@0 | 466 | address sep = _illegal_bytecode_sequence; |
aoqi@0 | 467 | address aep = _illegal_bytecode_sequence; |
aoqi@0 | 468 | address iep = _illegal_bytecode_sequence; |
aoqi@0 | 469 | address lep = _illegal_bytecode_sequence; |
aoqi@0 | 470 | address fep = _illegal_bytecode_sequence; |
aoqi@0 | 471 | address dep = _illegal_bytecode_sequence; |
aoqi@0 | 472 | address vep = _unimplemented_bytecode; |
aoqi@0 | 473 | address wep = _unimplemented_bytecode; |
aoqi@0 | 474 | // code for short & wide version of bytecode |
aoqi@0 | 475 | if (Bytecodes::is_defined(code)) { |
aoqi@0 | 476 | Template* t = TemplateTable::template_for(code); |
aoqi@0 | 477 | assert(t->is_valid(), "just checking"); |
aoqi@0 | 478 | set_short_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); |
aoqi@0 | 479 | } |
aoqi@0 | 480 | if (Bytecodes::wide_is_defined(code)) { |
aoqi@0 | 481 | Template* t = TemplateTable::template_for_wide(code); |
aoqi@0 | 482 | assert(t->is_valid(), "just checking"); |
aoqi@0 | 483 | set_wide_entry_point(t, wep); |
aoqi@0 | 484 | } |
aoqi@0 | 485 | // set entry points |
kevinw@8368 | 486 | EntryPoint entry(bep, zep, cep, sep, aep, iep, lep, fep, dep, vep); |
aoqi@0 | 487 | Interpreter::_normal_table.set_entry(code, entry); |
aoqi@0 | 488 | Interpreter::_wentry_point[code] = wep; |
aoqi@0 | 489 | } |
aoqi@0 | 490 | |
aoqi@0 | 491 | |
aoqi@0 | 492 | void TemplateInterpreterGenerator::set_wide_entry_point(Template* t, address& wep) { |
aoqi@0 | 493 | assert(t->is_valid(), "template must exist"); |
aoqi@0 | 494 | assert(t->tos_in() == vtos, "only vtos tos_in supported for wide instructions"); |
aoqi@0 | 495 | wep = __ pc(); generate_and_dispatch(t); |
aoqi@0 | 496 | } |
aoqi@0 | 497 | |
aoqi@0 | 498 | |
aoqi@0 | 499 | 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) { |
aoqi@0 | 500 | assert(t->is_valid(), "template must exist"); |
aoqi@0 | 501 | switch (t->tos_in()) { |
aoqi@0 | 502 | case btos: |
kevinw@8368 | 503 | case ztos: |
aoqi@0 | 504 | case ctos: |
aoqi@0 | 505 | case stos: |
aoqi@0 | 506 | ShouldNotReachHere(); // btos/ctos/stos should use itos. |
aoqi@0 | 507 | break; |
aoqi@0 | 508 | case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break; |
aoqi@0 | 509 | case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break; |
aoqi@0 | 510 | case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break; |
aoqi@0 | 511 | case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break; |
aoqi@0 | 512 | case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break; |
aoqi@0 | 513 | case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); break; |
aoqi@0 | 514 | default : ShouldNotReachHere(); break; |
aoqi@0 | 515 | } |
aoqi@0 | 516 | } |
aoqi@0 | 517 | |
aoqi@0 | 518 | |
aoqi@0 | 519 | //------------------------------------------------------------------------------------------------------------------------ |
aoqi@0 | 520 | |
aoqi@0 | 521 | void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) { |
aoqi@0 | 522 | if (PrintBytecodeHistogram) histogram_bytecode(t); |
aoqi@0 | 523 | #ifndef PRODUCT |
aoqi@0 | 524 | // debugging code |
aoqi@0 | 525 | if (CountBytecodes || TraceBytecodes || StopInterpreterAt > 0) count_bytecode(); |
aoqi@0 | 526 | if (PrintBytecodePairHistogram) histogram_bytecode_pair(t); |
aoqi@0 | 527 | if (TraceBytecodes) trace_bytecode(t); |
aoqi@0 | 528 | if (StopInterpreterAt > 0) stop_interpreter_at(); |
aoqi@0 | 529 | __ verify_FPU(1, t->tos_in()); |
aoqi@0 | 530 | #endif // !PRODUCT |
csahu@8316 | 531 | int step = 0; |
aoqi@0 | 532 | if (!t->does_dispatch()) { |
aoqi@0 | 533 | step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode()); |
aoqi@0 | 534 | if (tos_out == ilgl) tos_out = t->tos_out(); |
aoqi@0 | 535 | // compute bytecode size |
aoqi@0 | 536 | assert(step > 0, "just checkin'"); |
aoqi@0 | 537 | // setup stuff for dispatching next bytecode |
aoqi@0 | 538 | if (ProfileInterpreter && VerifyDataPointer |
aoqi@0 | 539 | && MethodData::bytecode_has_profile(t->bytecode())) { |
aoqi@0 | 540 | __ verify_method_data_pointer(); |
aoqi@0 | 541 | } |
aoqi@0 | 542 | __ dispatch_prolog(tos_out, step); |
aoqi@0 | 543 | } |
aoqi@0 | 544 | // generate template |
aoqi@0 | 545 | t->generate(_masm); |
aoqi@0 | 546 | // advance |
aoqi@0 | 547 | if (t->does_dispatch()) { |
aoqi@0 | 548 | #ifdef ASSERT |
aoqi@0 | 549 | // make sure execution doesn't go beyond this point if code is broken |
aoqi@0 | 550 | __ should_not_reach_here(); |
aoqi@0 | 551 | #endif // ASSERT |
aoqi@0 | 552 | } else { |
aoqi@0 | 553 | // dispatch to next bytecode |
aoqi@0 | 554 | __ dispatch_epilog(tos_out, step); |
aoqi@0 | 555 | } |
aoqi@0 | 556 | } |
aoqi@0 | 557 | |
aoqi@0 | 558 | //------------------------------------------------------------------------------------------------------------------------ |
aoqi@0 | 559 | // Entry points |
aoqi@0 | 560 | |
aoqi@0 | 561 | /** |
aoqi@0 | 562 | * Returns the return entry table for the given invoke bytecode. |
aoqi@0 | 563 | */ |
aoqi@0 | 564 | address* TemplateInterpreter::invoke_return_entry_table_for(Bytecodes::Code code) { |
aoqi@0 | 565 | switch (code) { |
aoqi@0 | 566 | case Bytecodes::_invokestatic: |
aoqi@0 | 567 | case Bytecodes::_invokespecial: |
aoqi@0 | 568 | case Bytecodes::_invokevirtual: |
aoqi@0 | 569 | case Bytecodes::_invokehandle: |
aoqi@0 | 570 | return Interpreter::invoke_return_entry_table(); |
aoqi@0 | 571 | case Bytecodes::_invokeinterface: |
aoqi@0 | 572 | return Interpreter::invokeinterface_return_entry_table(); |
aoqi@0 | 573 | case Bytecodes::_invokedynamic: |
aoqi@0 | 574 | return Interpreter::invokedynamic_return_entry_table(); |
aoqi@0 | 575 | default: |
aoqi@0 | 576 | fatal(err_msg("invalid bytecode: %s", Bytecodes::name(code))); |
aoqi@0 | 577 | return NULL; |
aoqi@0 | 578 | } |
aoqi@0 | 579 | } |
aoqi@0 | 580 | |
aoqi@0 | 581 | /** |
aoqi@0 | 582 | * Returns the return entry address for the given top-of-stack state and bytecode. |
aoqi@0 | 583 | */ |
aoqi@0 | 584 | address TemplateInterpreter::return_entry(TosState state, int length, Bytecodes::Code code) { |
aoqi@0 | 585 | guarantee(0 <= length && length < Interpreter::number_of_return_entries, "illegal length"); |
aoqi@0 | 586 | const int index = TosState_as_index(state); |
aoqi@0 | 587 | switch (code) { |
aoqi@0 | 588 | case Bytecodes::_invokestatic: |
aoqi@0 | 589 | case Bytecodes::_invokespecial: |
aoqi@0 | 590 | case Bytecodes::_invokevirtual: |
aoqi@0 | 591 | case Bytecodes::_invokehandle: |
aoqi@0 | 592 | return _invoke_return_entry[index]; |
aoqi@0 | 593 | case Bytecodes::_invokeinterface: |
aoqi@0 | 594 | return _invokeinterface_return_entry[index]; |
aoqi@0 | 595 | case Bytecodes::_invokedynamic: |
aoqi@0 | 596 | return _invokedynamic_return_entry[index]; |
aoqi@0 | 597 | default: |
aoqi@0 | 598 | assert(!Bytecodes::is_invoke(code), err_msg("invoke instructions should be handled separately: %s", Bytecodes::name(code))); |
aoqi@0 | 599 | return _return_entry[length].entry(state); |
aoqi@0 | 600 | } |
aoqi@0 | 601 | } |
aoqi@0 | 602 | |
aoqi@0 | 603 | |
aoqi@0 | 604 | address TemplateInterpreter::deopt_entry(TosState state, int length) { |
aoqi@0 | 605 | guarantee(0 <= length && length < Interpreter::number_of_deopt_entries, "illegal length"); |
aoqi@0 | 606 | return _deopt_entry[length].entry(state); |
aoqi@0 | 607 | } |
aoqi@0 | 608 | |
aoqi@0 | 609 | //------------------------------------------------------------------------------------------------------------------------ |
aoqi@0 | 610 | // Suport for invokes |
aoqi@0 | 611 | |
aoqi@0 | 612 | int TemplateInterpreter::TosState_as_index(TosState state) { |
aoqi@0 | 613 | assert( state < number_of_states , "Invalid state in TosState_as_index"); |
aoqi@0 | 614 | assert(0 <= (int)state && (int)state < TemplateInterpreter::number_of_return_addrs, "index out of bounds"); |
aoqi@0 | 615 | return (int)state; |
aoqi@0 | 616 | } |
aoqi@0 | 617 | |
aoqi@0 | 618 | |
aoqi@0 | 619 | //------------------------------------------------------------------------------------------------------------------------ |
aoqi@0 | 620 | // Safepoint suppport |
aoqi@0 | 621 | |
aoqi@0 | 622 | static inline void copy_table(address* from, address* to, int size) { |
aoqi@0 | 623 | // Copy non-overlapping tables. The copy has to occur word wise for MT safety. |
aoqi@0 | 624 | while (size-- > 0) *to++ = *from++; |
aoqi@0 | 625 | } |
aoqi@0 | 626 | |
aoqi@0 | 627 | void TemplateInterpreter::notice_safepoints() { |
aoqi@0 | 628 | if (!_notice_safepoints) { |
aoqi@0 | 629 | // switch to safepoint dispatch table |
aoqi@0 | 630 | _notice_safepoints = true; |
aoqi@0 | 631 | copy_table((address*)&_safept_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address)); |
aoqi@0 | 632 | } |
aoqi@0 | 633 | } |
aoqi@0 | 634 | |
aoqi@0 | 635 | // switch from the dispatch table which notices safepoints back to the |
aoqi@0 | 636 | // normal dispatch table. So that we can notice single stepping points, |
aoqi@0 | 637 | // keep the safepoint dispatch table if we are single stepping in JVMTI. |
aoqi@0 | 638 | // Note that the should_post_single_step test is exactly as fast as the |
aoqi@0 | 639 | // JvmtiExport::_enabled test and covers both cases. |
aoqi@0 | 640 | void TemplateInterpreter::ignore_safepoints() { |
aoqi@0 | 641 | if (_notice_safepoints) { |
aoqi@0 | 642 | if (!JvmtiExport::should_post_single_step()) { |
aoqi@0 | 643 | // switch to normal dispatch table |
aoqi@0 | 644 | _notice_safepoints = false; |
aoqi@0 | 645 | copy_table((address*)&_normal_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address)); |
aoqi@0 | 646 | } |
aoqi@0 | 647 | } |
aoqi@0 | 648 | } |
aoqi@0 | 649 | |
aoqi@0 | 650 | //------------------------------------------------------------------------------------------------------------------------ |
aoqi@0 | 651 | // Deoptimization support |
aoqi@0 | 652 | |
aoqi@0 | 653 | // If deoptimization happens, this function returns the point of next bytecode to continue execution |
aoqi@0 | 654 | address TemplateInterpreter::deopt_continue_after_entry(Method* method, address bcp, int callee_parameters, bool is_top_frame) { |
aoqi@0 | 655 | return AbstractInterpreter::deopt_continue_after_entry(method, bcp, callee_parameters, is_top_frame); |
aoqi@0 | 656 | } |
aoqi@0 | 657 | |
aoqi@0 | 658 | // If deoptimization happens, this function returns the point where the interpreter reexecutes |
aoqi@0 | 659 | // the bytecode. |
aoqi@0 | 660 | // Note: Bytecodes::_athrow (C1 only) and Bytecodes::_return are the special cases |
aoqi@0 | 661 | // that do not return "Interpreter::deopt_entry(vtos, 0)" |
aoqi@0 | 662 | address TemplateInterpreter::deopt_reexecute_entry(Method* method, address bcp) { |
aoqi@0 | 663 | assert(method->contains(bcp), "just checkin'"); |
aoqi@0 | 664 | Bytecodes::Code code = Bytecodes::java_code_at(method, bcp); |
aoqi@0 | 665 | if (code == Bytecodes::_return) { |
aoqi@0 | 666 | // This is used for deopt during registration of finalizers |
aoqi@0 | 667 | // during Object.<init>. We simply need to resume execution at |
aoqi@0 | 668 | // the standard return vtos bytecode to pop the frame normally. |
aoqi@0 | 669 | // reexecuting the real bytecode would cause double registration |
aoqi@0 | 670 | // of the finalizable object. |
aoqi@0 | 671 | return _normal_table.entry(Bytecodes::_return).entry(vtos); |
aoqi@0 | 672 | } else { |
aoqi@0 | 673 | return AbstractInterpreter::deopt_reexecute_entry(method, bcp); |
aoqi@0 | 674 | } |
aoqi@0 | 675 | } |
aoqi@0 | 676 | |
aoqi@0 | 677 | // If deoptimization happens, the interpreter should reexecute this bytecode. |
aoqi@0 | 678 | // This function mainly helps the compilers to set up the reexecute bit. |
aoqi@0 | 679 | bool TemplateInterpreter::bytecode_should_reexecute(Bytecodes::Code code) { |
aoqi@0 | 680 | if (code == Bytecodes::_return) { |
aoqi@0 | 681 | //Yes, we consider Bytecodes::_return as a special case of reexecution |
aoqi@0 | 682 | return true; |
aoqi@0 | 683 | } else { |
aoqi@0 | 684 | return AbstractInterpreter::bytecode_should_reexecute(code); |
aoqi@0 | 685 | } |
aoqi@0 | 686 | } |
aoqi@0 | 687 | |
aoqi@0 | 688 | #endif // !CC_INTERP |