1472N/A * or visit www.oracle.com if you need additional information or have any
1879N/A#include "precompiled.hpp"
2262N/A#include "asm/assembler.hpp"
1879N/A#include "c1/c1_Defs.hpp"
1879N/A#include "c1/c1_MacroAssembler.hpp"
1879N/A#include "c1/c1_Runtime1.hpp"
1879N/A#include "interpreter/interpreter.hpp"
1879N/A#include "nativeInst_x86.hpp"
1879N/A#include "oops/compiledICHolderOop.hpp"
1879N/A#include "oops/oop.inline.hpp"
1879N/A#include "prims/jvmtiExport.hpp"
1879N/A#include "register_x86.hpp"
1879N/A#include "runtime/sharedRuntime.hpp"
1879N/A#include "runtime/signature.hpp"
1879N/A#include "runtime/vframeArray.hpp"
1879N/A#include "vmreg_x86.inline.hpp"
0N/Aint StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, int args_size) {
304N/A const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); // is callee-saved register (Visual C++ calling conventions)
0N/A assert(!(oop_result1->is_valid() || oop_result2->is_valid()) || oop_result1 != oop_result2, "registers must be different");
3575N/A if (!align_stack) {
3575N/A if (!align_stack) {
0N/A return call_offset;
0N/Aint StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1) {
0N/Aint StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2) {
0N/Aint StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2, Register arg3) {
304N/A float_regs_as_doubles_off = xmm_regs_as_doubles_off + xmm_regs_as_doubles_size_in_slots, // 160
0N/A bool save_fpu_registers = true) {
304N/A LP64_ONLY(assert((reg_save_frame_size * VMRegImpl::stack_slot_size) % 16 == 0, "must be 16 byte aligned");)
0N/A // locations are offsets from sp after runtime call; num_rt_args is number of arguments in call, including thread
304N/A map->set_callee_saved(VMRegImpl::stack2reg(raxH_off + num_rt_args), rax->as_VMReg()->next());
304N/A map->set_callee_saved(VMRegImpl::stack2reg(rcxH_off + num_rt_args), rcx->as_VMReg()->next());
304N/A map->set_callee_saved(VMRegImpl::stack2reg(rdxH_off + num_rt_args), rdx->as_VMReg()->next());
304N/A map->set_callee_saved(VMRegImpl::stack2reg(rbxH_off + num_rt_args), rbx->as_VMReg()->next());
304N/A map->set_callee_saved(VMRegImpl::stack2reg(rsiH_off + num_rt_args), rsi->as_VMReg()->next());
304N/A map->set_callee_saved(VMRegImpl::stack2reg(rdiH_off + num_rt_args), rdi->as_VMReg()->next());
304N/A map->set_callee_saved(VMRegImpl::stack2reg(r10H_off + num_rt_args), r10->as_VMReg()->next());
304N/A map->set_callee_saved(VMRegImpl::stack2reg(r11H_off + num_rt_args), r11->as_VMReg()->next());
304N/A map->set_callee_saved(VMRegImpl::stack2reg(r12H_off + num_rt_args), r12->as_VMReg()->next());
304N/A map->set_callee_saved(VMRegImpl::stack2reg(r13H_off + num_rt_args), r13->as_VMReg()->next());
304N/A map->set_callee_saved(VMRegImpl::stack2reg(r14H_off + num_rt_args), r14->as_VMReg()->next());
304N/A map->set_callee_saved(VMRegImpl::stack2reg(r15H_off + num_rt_args), r15->as_VMReg()->next());
0N/A if (save_fpu_registers) {
0N/A bool save_fpu_registers = true) {
0N/A if (save_fpu_registers) {
304N/A __ cmpw(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size), StubRoutines::fpu_cntrl_wrd_std());
304N/A __ movw(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size), StubRoutines::fpu_cntrl_wrd_std());
0N/A if (restore_fpu_registers) {
0N/Astatic void restore_live_registers_except_rax(StubAssembler* sasm, bool restore_fpu_registers = true) {
0N/A// has_argument: true if the exception needs an argument (passed on stack because registers must be preserved)
0N/AOopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address target, bool has_argument) {
0N/A if (has_argument) {
2168N/A case forward_exception_id:
2168N/A case handle_exception_id:
2168N/A const int frame_size = 2 /*BP, return address*/ NOT_LP64(+ 1 /*thread*/) WIN64_ONLY(+ frame::arg_reg_save_area_bytes / BytesPerWord);
2168N/A default: ShouldNotReachHere();
0N/A int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
0N/A // only rax, is valid at this time, all other registers have been destroyed by the runtime call
2168N/A case forward_exception_id:
2168N/A case handle_exception_id:
2168N/A default: ShouldNotReachHere();
1295N/A __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc);
1295N/A // Only RAX and RSI are valid at this time, all other registers have been destroyed by the call.
0N/A // default value; overwritten for some optimized stubs that are called from methods that do not use the fpu
0N/A case forward_exception_id:
0N/A case new_instance_id:
0N/A case fast_new_instance_id:
3051N/A __ cmpb(Address(klass, instanceKlass::init_state_offset()), instanceKlass::fully_initialized);
1988N/A __ tlab_refill(retry_tlab, try_eden, slow_path); // does not destroy rdx (klass), returns rdi
0N/A case counter_overflow_id:
1703N/A int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
0N/A case new_type_array_id:
0N/A case new_object_array_id:
3042N/A __ movb(t1, Address(klass, in_bytes(Klass::layout_helper_offset()) + (Klass::_lh_header_size_shift / BitsPerByte)));
3042N/A __ movb(t1, Address(klass, in_bytes(Klass::layout_helper_offset()) + (Klass::_lh_header_size_shift / BitsPerByte)));
0N/A call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
0N/A call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
0N/A case new_multi_array_id:
0N/A int call_offset = __ call_RT(rax, noreg, CAST_FROM_FN_PTR(address, new_multi_array), rax, rbx, rcx);
0N/A case register_finalizer_id:
0N/A oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_range_check_exception), true);
0N/A case throw_index_exception_id:
0N/A oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_index_exception), true);
0N/A case throw_div0_exception_id:
0N/A oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_div0_exception), false);
0N/A oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false);
0N/A case handle_exception_id:
0N/A case unwind_exception_id:
2053N/A oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
0N/A oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
0N/A oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
0N/A case slow_subtype_check_id:
0N/A case monitorenter_nofpu_id:
0N/A save_fpu_registers = false;
0N/A case monitorenter_id:
0N/A case monitorexit_nofpu_id:
0N/A save_fpu_registers = false;
0N/A case monitorexit_id:
2886N/A case deoptimize_id:
0N/A case access_field_patching_id:
0N/A case load_klass_patching_id:
0N/A case dtrace_object_alloc_id:
0N/A case fpu2long_stub_id:
342N/A case g1_pre_barrier_slow_id: