212 T_DOUBLE , |
236 T_DOUBLE , |
213 T_OBJECT |
237 T_OBJECT |
214 }; |
238 }; |
215 |
239 |
216 void TemplateInterpreterGenerator::generate_all() { |
240 void TemplateInterpreterGenerator::generate_all() { |
217 AbstractInterpreterGenerator::generate_all(); |
241 // Loop, in case we need several variants of the interpreter entries |
218 |
242 do { |
219 { CodeletMark cm(_masm, "error exits"); |
243 if (!CodeCacheExtensions::skip_code_generation()) { |
220 _unimplemented_bytecode = generate_error_exit("unimplemented bytecode"); |
244 // bypass code generation when useless |
221 _illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified"); |
245 AbstractInterpreterGenerator::generate_all(); |
222 } |
246 |
|
247 { CodeletMark cm(_masm, "error exits"); |
|
248 _unimplemented_bytecode = generate_error_exit("unimplemented bytecode"); |
|
249 _illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified"); |
|
250 } |
223 |
251 |
224 #ifndef PRODUCT |
252 #ifndef PRODUCT |
225 if (TraceBytecodes) { |
253 if (TraceBytecodes) { |
226 CodeletMark cm(_masm, "bytecode tracing support"); |
254 CodeletMark cm(_masm, "bytecode tracing support"); |
227 Interpreter::_trace_code = |
255 Interpreter::_trace_code = |
228 EntryPoint( |
256 EntryPoint( |
229 generate_trace_code(btos), |
257 generate_trace_code(btos), |
230 generate_trace_code(ctos), |
258 generate_trace_code(ctos), |
231 generate_trace_code(stos), |
259 generate_trace_code(stos), |
232 generate_trace_code(atos), |
260 generate_trace_code(atos), |
233 generate_trace_code(itos), |
261 generate_trace_code(itos), |
234 generate_trace_code(ltos), |
262 generate_trace_code(ltos), |
235 generate_trace_code(ftos), |
263 generate_trace_code(ftos), |
236 generate_trace_code(dtos), |
264 generate_trace_code(dtos), |
237 generate_trace_code(vtos) |
265 generate_trace_code(vtos) |
238 ); |
266 ); |
239 } |
267 } |
240 #endif // !PRODUCT |
268 #endif // !PRODUCT |
241 |
269 |
242 { CodeletMark cm(_masm, "return entry points"); |
270 { CodeletMark cm(_masm, "return entry points"); |
243 const int index_size = sizeof(u2); |
271 const int index_size = sizeof(u2); |
244 for (int i = 0; i < Interpreter::number_of_return_entries; i++) { |
272 for (int i = 0; i < Interpreter::number_of_return_entries; i++) { |
245 Interpreter::_return_entry[i] = |
273 Interpreter::_return_entry[i] = |
246 EntryPoint( |
274 EntryPoint( |
247 generate_return_entry_for(itos, i, index_size), |
275 generate_return_entry_for(itos, i, index_size), |
248 generate_return_entry_for(itos, i, index_size), |
276 generate_return_entry_for(itos, i, index_size), |
249 generate_return_entry_for(itos, i, index_size), |
277 generate_return_entry_for(itos, i, index_size), |
250 generate_return_entry_for(atos, i, index_size), |
278 generate_return_entry_for(atos, i, index_size), |
251 generate_return_entry_for(itos, i, index_size), |
279 generate_return_entry_for(itos, i, index_size), |
252 generate_return_entry_for(ltos, i, index_size), |
280 generate_return_entry_for(ltos, i, index_size), |
253 generate_return_entry_for(ftos, i, index_size), |
281 generate_return_entry_for(ftos, i, index_size), |
254 generate_return_entry_for(dtos, i, index_size), |
282 generate_return_entry_for(dtos, i, index_size), |
255 generate_return_entry_for(vtos, i, index_size) |
283 generate_return_entry_for(vtos, i, index_size) |
256 ); |
284 ); |
|
285 } |
|
286 } |
|
287 |
|
288 { CodeletMark cm(_masm, "invoke return entry points"); |
|
289 const TosState states[] = {itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos}; |
|
290 const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic); |
|
291 const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface); |
|
292 const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic); |
|
293 |
|
294 for (int i = 0; i < Interpreter::number_of_return_addrs; i++) { |
|
295 TosState state = states[i]; |
|
296 Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2)); |
|
297 Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2)); |
|
298 Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4)); |
|
299 } |
|
300 } |
|
301 |
|
302 { CodeletMark cm(_masm, "earlyret entry points"); |
|
303 Interpreter::_earlyret_entry = |
|
304 EntryPoint( |
|
305 generate_earlyret_entry_for(btos), |
|
306 generate_earlyret_entry_for(ctos), |
|
307 generate_earlyret_entry_for(stos), |
|
308 generate_earlyret_entry_for(atos), |
|
309 generate_earlyret_entry_for(itos), |
|
310 generate_earlyret_entry_for(ltos), |
|
311 generate_earlyret_entry_for(ftos), |
|
312 generate_earlyret_entry_for(dtos), |
|
313 generate_earlyret_entry_for(vtos) |
|
314 ); |
|
315 } |
|
316 |
|
317 { CodeletMark cm(_masm, "deoptimization entry points"); |
|
318 for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) { |
|
319 Interpreter::_deopt_entry[i] = |
|
320 EntryPoint( |
|
321 generate_deopt_entry_for(itos, i), |
|
322 generate_deopt_entry_for(itos, i), |
|
323 generate_deopt_entry_for(itos, i), |
|
324 generate_deopt_entry_for(atos, i), |
|
325 generate_deopt_entry_for(itos, i), |
|
326 generate_deopt_entry_for(ltos, i), |
|
327 generate_deopt_entry_for(ftos, i), |
|
328 generate_deopt_entry_for(dtos, i), |
|
329 generate_deopt_entry_for(vtos, i) |
|
330 ); |
|
331 } |
|
332 } |
|
333 |
|
334 { CodeletMark cm(_masm, "result handlers for native calls"); |
|
335 // The various result converter stublets. |
|
336 int is_generated[Interpreter::number_of_result_handlers]; |
|
337 memset(is_generated, 0, sizeof(is_generated)); |
|
338 |
|
339 for (int i = 0; i < Interpreter::number_of_result_handlers; i++) { |
|
340 BasicType type = types[i]; |
|
341 if (!is_generated[Interpreter::BasicType_as_index(type)]++) { |
|
342 Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type); |
|
343 } |
|
344 } |
|
345 } |
|
346 |
|
347 { CodeletMark cm(_masm, "continuation entry points"); |
|
348 Interpreter::_continuation_entry = |
|
349 EntryPoint( |
|
350 generate_continuation_for(btos), |
|
351 generate_continuation_for(ctos), |
|
352 generate_continuation_for(stos), |
|
353 generate_continuation_for(atos), |
|
354 generate_continuation_for(itos), |
|
355 generate_continuation_for(ltos), |
|
356 generate_continuation_for(ftos), |
|
357 generate_continuation_for(dtos), |
|
358 generate_continuation_for(vtos) |
|
359 ); |
|
360 } |
|
361 |
|
362 { CodeletMark cm(_masm, "safepoint entry points"); |
|
363 Interpreter::_safept_entry = |
|
364 EntryPoint( |
|
365 generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
366 generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
367 generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
368 generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
369 generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
370 generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
371 generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
372 generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
373 generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)) |
|
374 ); |
|
375 } |
|
376 |
|
377 { CodeletMark cm(_masm, "exception handling"); |
|
378 // (Note: this is not safepoint safe because thread may return to compiled code) |
|
379 generate_throw_exception(); |
|
380 } |
|
381 |
|
382 { CodeletMark cm(_masm, "throw exception entrypoints"); |
|
383 Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException"); |
|
384 Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException" ); |
|
385 Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException" , "/ by zero"); |
|
386 Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler(); |
|
387 Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException" , NULL ); |
|
388 Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler(); |
|
389 } |
|
390 |
|
391 |
|
392 |
|
393 #define method_entry(kind) \ |
|
394 { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \ |
|
395 Interpreter::_entry_table[Interpreter::kind] = ((InterpreterGenerator*)this)->generate_method_entry(Interpreter::kind); \ |
|
396 } |
|
397 |
|
398 // all non-native method kinds |
|
399 method_entry(zerolocals) |
|
400 method_entry(zerolocals_synchronized) |
|
401 method_entry(empty) |
|
402 method_entry(accessor) |
|
403 method_entry(abstract) |
|
404 method_entry(java_lang_math_sin ) |
|
405 method_entry(java_lang_math_cos ) |
|
406 method_entry(java_lang_math_tan ) |
|
407 method_entry(java_lang_math_abs ) |
|
408 method_entry(java_lang_math_sqrt ) |
|
409 method_entry(java_lang_math_log ) |
|
410 method_entry(java_lang_math_log10) |
|
411 method_entry(java_lang_math_exp ) |
|
412 method_entry(java_lang_math_pow ) |
|
413 method_entry(java_lang_ref_reference_get) |
|
414 |
|
415 if (UseCRC32Intrinsics) { |
|
416 method_entry(java_util_zip_CRC32_update) |
|
417 method_entry(java_util_zip_CRC32_updateBytes) |
|
418 method_entry(java_util_zip_CRC32_updateByteBuffer) |
|
419 } |
|
420 |
|
421 initialize_method_handle_entries(); |
|
422 |
|
423 // all native method kinds (must be one contiguous block) |
|
424 Interpreter::_native_entry_begin = Interpreter::code()->code_end(); |
|
425 method_entry(native) |
|
426 method_entry(native_synchronized) |
|
427 Interpreter::_native_entry_end = Interpreter::code()->code_end(); |
|
428 |
|
429 #undef method_entry |
|
430 |
|
431 // Bytecodes |
|
432 set_entry_points_for_all_bytes(); |
257 } |
433 } |
258 } |
434 } while (CodeCacheExtensions::needs_other_interpreter_variant()); |
259 |
435 |
260 { CodeletMark cm(_masm, "invoke return entry points"); |
436 // installation of code in other places in the runtime |
261 const TosState states[] = {itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos}; |
437 // (ExcutableCodeManager calls not needed to copy the entries) |
262 const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic); |
|
263 const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface); |
|
264 const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic); |
|
265 |
|
266 for (int i = 0; i < Interpreter::number_of_return_addrs; i++) { |
|
267 TosState state = states[i]; |
|
268 Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2)); |
|
269 Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2)); |
|
270 Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4)); |
|
271 } |
|
272 } |
|
273 |
|
274 { CodeletMark cm(_masm, "earlyret entry points"); |
|
275 Interpreter::_earlyret_entry = |
|
276 EntryPoint( |
|
277 generate_earlyret_entry_for(btos), |
|
278 generate_earlyret_entry_for(ctos), |
|
279 generate_earlyret_entry_for(stos), |
|
280 generate_earlyret_entry_for(atos), |
|
281 generate_earlyret_entry_for(itos), |
|
282 generate_earlyret_entry_for(ltos), |
|
283 generate_earlyret_entry_for(ftos), |
|
284 generate_earlyret_entry_for(dtos), |
|
285 generate_earlyret_entry_for(vtos) |
|
286 ); |
|
287 } |
|
288 |
|
289 { CodeletMark cm(_masm, "deoptimization entry points"); |
|
290 for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) { |
|
291 Interpreter::_deopt_entry[i] = |
|
292 EntryPoint( |
|
293 generate_deopt_entry_for(itos, i), |
|
294 generate_deopt_entry_for(itos, i), |
|
295 generate_deopt_entry_for(itos, i), |
|
296 generate_deopt_entry_for(atos, i), |
|
297 generate_deopt_entry_for(itos, i), |
|
298 generate_deopt_entry_for(ltos, i), |
|
299 generate_deopt_entry_for(ftos, i), |
|
300 generate_deopt_entry_for(dtos, i), |
|
301 generate_deopt_entry_for(vtos, i) |
|
302 ); |
|
303 } |
|
304 } |
|
305 |
|
306 { CodeletMark cm(_masm, "result handlers for native calls"); |
|
307 // The various result converter stublets. |
|
308 int is_generated[Interpreter::number_of_result_handlers]; |
|
309 memset(is_generated, 0, sizeof(is_generated)); |
|
310 |
|
311 for (int i = 0; i < Interpreter::number_of_result_handlers; i++) { |
|
312 BasicType type = types[i]; |
|
313 if (!is_generated[Interpreter::BasicType_as_index(type)]++) { |
|
314 Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type); |
|
315 } |
|
316 } |
|
317 } |
|
318 |
|
319 { CodeletMark cm(_masm, "continuation entry points"); |
|
320 Interpreter::_continuation_entry = |
|
321 EntryPoint( |
|
322 generate_continuation_for(btos), |
|
323 generate_continuation_for(ctos), |
|
324 generate_continuation_for(stos), |
|
325 generate_continuation_for(atos), |
|
326 generate_continuation_for(itos), |
|
327 generate_continuation_for(ltos), |
|
328 generate_continuation_for(ftos), |
|
329 generate_continuation_for(dtos), |
|
330 generate_continuation_for(vtos) |
|
331 ); |
|
332 } |
|
333 |
|
334 { CodeletMark cm(_masm, "safepoint entry points"); |
|
335 Interpreter::_safept_entry = |
|
336 EntryPoint( |
|
337 generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
338 generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
339 generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
340 generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
341 generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
342 generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
343 generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
344 generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), |
|
345 generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)) |
|
346 ); |
|
347 } |
|
348 |
|
349 { CodeletMark cm(_masm, "exception handling"); |
|
350 // (Note: this is not safepoint safe because thread may return to compiled code) |
|
351 generate_throw_exception(); |
|
352 } |
|
353 |
|
354 { CodeletMark cm(_masm, "throw exception entrypoints"); |
|
355 Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException"); |
|
356 Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException" ); |
|
357 Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException" , "/ by zero"); |
|
358 Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler(); |
|
359 Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException" , NULL ); |
|
360 Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler(); |
|
361 } |
|
362 |
|
363 |
|
364 |
|
365 #define method_entry(kind) \ |
|
366 { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \ |
|
367 Interpreter::_entry_table[Interpreter::kind] = ((InterpreterGenerator*)this)->generate_method_entry(Interpreter::kind); \ |
|
368 } |
|
369 |
|
370 // all non-native method kinds |
|
371 method_entry(zerolocals) |
|
372 method_entry(zerolocals_synchronized) |
|
373 method_entry(empty) |
|
374 method_entry(accessor) |
|
375 method_entry(abstract) |
|
376 method_entry(java_lang_math_sin ) |
|
377 method_entry(java_lang_math_cos ) |
|
378 method_entry(java_lang_math_tan ) |
|
379 method_entry(java_lang_math_abs ) |
|
380 method_entry(java_lang_math_sqrt ) |
|
381 method_entry(java_lang_math_log ) |
|
382 method_entry(java_lang_math_log10) |
|
383 method_entry(java_lang_math_exp ) |
|
384 method_entry(java_lang_math_pow ) |
|
385 method_entry(java_lang_ref_reference_get) |
|
386 |
|
387 if (UseCRC32Intrinsics) { |
|
388 method_entry(java_util_zip_CRC32_update) |
|
389 method_entry(java_util_zip_CRC32_updateBytes) |
|
390 method_entry(java_util_zip_CRC32_updateByteBuffer) |
|
391 } |
|
392 |
|
393 initialize_method_handle_entries(); |
|
394 |
|
395 // all native method kinds (must be one contiguous block) |
|
396 Interpreter::_native_entry_begin = Interpreter::code()->code_end(); |
|
397 method_entry(native) |
|
398 method_entry(native_synchronized) |
|
399 Interpreter::_native_entry_end = Interpreter::code()->code_end(); |
|
400 |
|
401 #undef method_entry |
|
402 |
|
403 // Bytecodes |
|
404 set_entry_points_for_all_bytes(); |
|
405 set_safepoints_for_all_bytes(); |
438 set_safepoints_for_all_bytes(); |
406 } |
439 } |
407 |
440 |
408 //------------------------------------------------------------------------------------------------------------------------ |
441 //------------------------------------------------------------------------------------------------------------------------ |
409 |
442 |