182 EntryPoint TemplateInterpreter::_earlyret_entry; |
182 EntryPoint TemplateInterpreter::_earlyret_entry; |
183 EntryPoint TemplateInterpreter::_deopt_entry [TemplateInterpreter::number_of_deopt_entries ]; |
183 EntryPoint TemplateInterpreter::_deopt_entry [TemplateInterpreter::number_of_deopt_entries ]; |
184 EntryPoint TemplateInterpreter::_continuation_entry; |
184 EntryPoint TemplateInterpreter::_continuation_entry; |
185 EntryPoint TemplateInterpreter::_safept_entry; |
185 EntryPoint TemplateInterpreter::_safept_entry; |
186 |
186 |
187 address TemplateInterpreter::_return_3_addrs_by_index[TemplateInterpreter::number_of_return_addrs]; |
187 address TemplateInterpreter::_invoke_return_entry[TemplateInterpreter::number_of_return_addrs]; |
188 address TemplateInterpreter::_return_5_addrs_by_index[TemplateInterpreter::number_of_return_addrs]; |
188 address TemplateInterpreter::_invokeinterface_return_entry[TemplateInterpreter::number_of_return_addrs]; |
|
189 address TemplateInterpreter::_invokedynamic_return_entry[TemplateInterpreter::number_of_return_addrs]; |
189 |
190 |
190 DispatchTable TemplateInterpreter::_active_table; |
191 DispatchTable TemplateInterpreter::_active_table; |
191 DispatchTable TemplateInterpreter::_normal_table; |
192 DispatchTable TemplateInterpreter::_normal_table; |
192 DispatchTable TemplateInterpreter::_safept_table; |
193 DispatchTable TemplateInterpreter::_safept_table; |
193 address TemplateInterpreter::_wentry_point[DispatchTable::length]; |
194 address TemplateInterpreter::_wentry_point[DispatchTable::length]; |
235 ); |
236 ); |
236 } |
237 } |
237 #endif // !PRODUCT |
238 #endif // !PRODUCT |
238 |
239 |
239 { CodeletMark cm(_masm, "return entry points"); |
240 { CodeletMark cm(_masm, "return entry points"); |
|
241 const int index_size = sizeof(u2); |
240 for (int i = 0; i < Interpreter::number_of_return_entries; i++) { |
242 for (int i = 0; i < Interpreter::number_of_return_entries; i++) { |
241 Interpreter::_return_entry[i] = |
243 Interpreter::_return_entry[i] = |
242 EntryPoint( |
244 EntryPoint( |
243 generate_return_entry_for(itos, i), |
245 generate_return_entry_for(itos, i, index_size), |
244 generate_return_entry_for(itos, i), |
246 generate_return_entry_for(itos, i, index_size), |
245 generate_return_entry_for(itos, i), |
247 generate_return_entry_for(itos, i, index_size), |
246 generate_return_entry_for(atos, i), |
248 generate_return_entry_for(atos, i, index_size), |
247 generate_return_entry_for(itos, i), |
249 generate_return_entry_for(itos, i, index_size), |
248 generate_return_entry_for(ltos, i), |
250 generate_return_entry_for(ltos, i, index_size), |
249 generate_return_entry_for(ftos, i), |
251 generate_return_entry_for(ftos, i, index_size), |
250 generate_return_entry_for(dtos, i), |
252 generate_return_entry_for(dtos, i, index_size), |
251 generate_return_entry_for(vtos, i) |
253 generate_return_entry_for(vtos, i, index_size) |
252 ); |
254 ); |
|
255 } |
|
256 } |
|
257 |
|
258 { CodeletMark cm(_masm, "invoke return entry points"); |
|
259 const TosState states[] = {itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos}; |
|
260 const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic); |
|
261 const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface); |
|
262 const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic); |
|
263 |
|
264 for (int i = 0; i < Interpreter::number_of_return_addrs; i++) { |
|
265 TosState state = states[i]; |
|
266 Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2)); |
|
267 Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2)); |
|
268 Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4)); |
253 } |
269 } |
254 } |
270 } |
255 |
271 |
256 { CodeletMark cm(_masm, "earlyret entry points"); |
272 { CodeletMark cm(_masm, "earlyret entry points"); |
257 Interpreter::_earlyret_entry = |
273 Interpreter::_earlyret_entry = |
294 BasicType type = types[i]; |
310 BasicType type = types[i]; |
295 if (!is_generated[Interpreter::BasicType_as_index(type)]++) { |
311 if (!is_generated[Interpreter::BasicType_as_index(type)]++) { |
296 Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type); |
312 Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type); |
297 } |
313 } |
298 } |
314 } |
299 } |
|
300 |
|
301 for (int j = 0; j < number_of_states; j++) { |
|
302 const TosState states[] = {btos, ctos, stos, itos, ltos, ftos, dtos, atos, vtos}; |
|
303 int index = Interpreter::TosState_as_index(states[j]); |
|
304 Interpreter::_return_3_addrs_by_index[index] = Interpreter::return_entry(states[j], 3); |
|
305 Interpreter::_return_5_addrs_by_index[index] = Interpreter::return_entry(states[j], 5); |
|
306 } |
315 } |
307 |
316 |
308 { CodeletMark cm(_masm, "continuation entry points"); |
317 { CodeletMark cm(_masm, "continuation entry points"); |
309 Interpreter::_continuation_entry = |
318 Interpreter::_continuation_entry = |
310 EntryPoint( |
319 EntryPoint( |
532 } |
541 } |
533 |
542 |
534 //------------------------------------------------------------------------------------------------------------------------ |
543 //------------------------------------------------------------------------------------------------------------------------ |
535 // Entry points |
544 // Entry points |
536 |
545 |
537 address TemplateInterpreter::return_entry(TosState state, int length) { |
546 /** |
|
547 * Returns the return entry table for the given invoke bytecode. |
|
548 */ |
|
549 address* TemplateInterpreter::invoke_return_entry_table_for(Bytecodes::Code code) { |
|
550 switch (code) { |
|
551 case Bytecodes::_invokestatic: |
|
552 case Bytecodes::_invokespecial: |
|
553 case Bytecodes::_invokevirtual: |
|
554 case Bytecodes::_invokehandle: |
|
555 return Interpreter::invoke_return_entry_table(); |
|
556 case Bytecodes::_invokeinterface: |
|
557 return Interpreter::invokeinterface_return_entry_table(); |
|
558 case Bytecodes::_invokedynamic: |
|
559 return Interpreter::invokedynamic_return_entry_table(); |
|
560 default: |
|
561 fatal(err_msg("invalid bytecode: %s", Bytecodes::name(code))); |
|
562 return NULL; |
|
563 } |
|
564 } |
|
565 |
|
566 /** |
|
567 * Returns the return entry address for the given top-of-stack state and bytecode. |
|
568 */ |
|
569 address TemplateInterpreter::return_entry(TosState state, int length, Bytecodes::Code code) { |
538 guarantee(0 <= length && length < Interpreter::number_of_return_entries, "illegal length"); |
570 guarantee(0 <= length && length < Interpreter::number_of_return_entries, "illegal length"); |
539 return _return_entry[length].entry(state); |
571 const int index = TosState_as_index(state); |
|
572 switch (code) { |
|
573 case Bytecodes::_invokestatic: |
|
574 case Bytecodes::_invokespecial: |
|
575 case Bytecodes::_invokevirtual: |
|
576 case Bytecodes::_invokehandle: |
|
577 return _invoke_return_entry[index]; |
|
578 case Bytecodes::_invokeinterface: |
|
579 return _invokeinterface_return_entry[index]; |
|
580 case Bytecodes::_invokedynamic: |
|
581 return _invokedynamic_return_entry[index]; |
|
582 default: |
|
583 assert(!Bytecodes::is_invoke(code), err_msg("invoke instructions should be handled separately: %s", Bytecodes::name(code))); |
|
584 return _return_entry[length].entry(state); |
|
585 } |
540 } |
586 } |
541 |
587 |
542 |
588 |
543 address TemplateInterpreter::deopt_entry(TosState state, int length) { |
589 address TemplateInterpreter::deopt_entry(TosState state, int length) { |
544 guarantee(0 <= length && length < Interpreter::number_of_deopt_entries, "illegal length"); |
590 guarantee(0 <= length && length < Interpreter::number_of_deopt_entries, "illegal length"); |