< prev index next >

src/hotspot/cpu/x86/stubGenerator_x86_64.cpp

Print this page




 319     __ BIND(loop);
 320     __ movptr(rax, Address(c_rarg2, 0));// get parameter
 321     __ addptr(c_rarg2, wordSize);       // advance to next parameter
 322     __ decrementl(c_rarg1);             // decrement counter
 323     __ push(rax);                       // pass parameter
 324     __ jcc(Assembler::notZero, loop);
 325 
 326     // call Java function
 327     __ BIND(parameters_done);
 328     __ movptr(rbx, method);             // get Method*
 329     __ movptr(c_rarg1, entry_point);    // get entry_point
 330     __ mov(r13, rsp);                   // set sender sp
 331     BLOCK_COMMENT("call Java function");
 332     __ call(c_rarg1);
 333 
 334     BLOCK_COMMENT("call_stub_return_address:");
 335     return_address = __ pc();
 336 
 337     // store result depending on type (everything that is not
 338     // T_OBJECT, T_VALUETYPE, T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT)
 339     __ movptr(c_rarg0, result);
 340     Label is_long, is_float, is_double, exit;
 341     __ movl(c_rarg1, result_type);
 342     __ cmpl(c_rarg1, T_OBJECT);
 343     __ jcc(Assembler::equal, is_long);
 344     __ cmpl(c_rarg1, T_VALUETYPE);


 345     __ jcc(Assembler::equal, is_long);
 346     __ cmpl(c_rarg1, T_LONG);
 347     __ jcc(Assembler::equal, is_long);
 348     __ cmpl(c_rarg1, T_FLOAT);
 349     __ jcc(Assembler::equal, is_float);
 350     __ cmpl(c_rarg1, T_DOUBLE);
 351     __ jcc(Assembler::equal, is_double);
 352 
 353     // handle T_INT case
 354     __ movl(Address(c_rarg0, 0), rax);
 355 
 356     __ BIND(exit);
 357 
 358     // pop parameters
 359     __ lea(rsp, rsp_after_call);
 360 
 361 #ifdef ASSERT
 362     // verify that threads correspond
 363     {
 364      Label L1, L2, L3;
 365       __ cmpptr(r15_thread, thread);
 366       __ jcc(Assembler::equal, L1);
 367       __ stop("StubRoutines::call_stub: r15_thread is corrupted");
 368       __ bind(L1);
 369       __ get_thread(rbx);
 370       __ cmpptr(r15_thread, thread);
 371       __ jcc(Assembler::equal, L2);
 372       __ stop("StubRoutines::call_stub: r15_thread is modified by call");
 373       __ bind(L2);
 374       __ cmpptr(r15_thread, rbx);


 396     __ movptr(r13, r13_save);
 397     __ movptr(r12, r12_save);
 398     __ movptr(rbx, rbx_save);
 399 
 400 #ifdef _WIN64
 401     __ movptr(rdi, rdi_save);
 402     __ movptr(rsi, rsi_save);
 403 #else
 404     __ ldmxcsr(mxcsr_save);
 405 #endif
 406 
 407     // restore rsp
 408     __ addptr(rsp, -rsp_after_call_off * wordSize);
 409 
 410     // return
 411     __ vzeroupper();
 412     __ pop(rbp);
 413     __ ret(0);
 414 
 415     // handle return types different from T_INT






 416     __ BIND(is_long);
 417     __ movq(Address(c_rarg0, 0), rax);
 418     __ jmp(exit);
 419 
 420     __ BIND(is_float);
 421     __ movflt(Address(c_rarg0, 0), xmm0);
 422     __ jmp(exit);
 423 
 424     __ BIND(is_double);
 425     __ movdbl(Address(c_rarg0, 0), xmm0);
 426     __ jmp(exit);
 427 
 428     return start;
 429   }
 430 
 431   // Return point for a Java call if there's an exception thrown in
 432   // Java code.  The exception is caught and transformed into a
 433   // pending exception stored in JavaThread that can be tested from
 434   // within the VM.
 435   //
 436   // Note: Usually the parameters are removed by the callee. In case
 437   // of an exception crossing an activation frame boundary, that is
 438   // not the case if the callee is compiled code => need to setup the
 439   // rsp.
 440   //
 441   // rax: exception oop
 442 
 443   address generate_catch_exception() {
 444     StubCodeMark mark(this, "StubRoutines", "catch_exception");
 445     address start = __ pc();


5881 
5882     RuntimeStub* stub = RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_in_words, oop_maps, false);
5883     return stub->entry_point();
5884   }
5885 
5886   // Initialization
5887   void generate_initial() {
5888     // Generates all stubs and initializes the entry points
5889 
5890     // This platform-specific settings are needed by generate_call_stub()
5891     create_control_words();
5892 
5893     // entry points that exist in all platforms Note: This is code
5894     // that could be shared among different platforms - however the
5895     // benefit seems to be smaller than the disadvantage of having a
5896     // much more complicated generator structure. See also comment in
5897     // stubRoutines.hpp.
5898 
5899     StubRoutines::_forward_exception_entry = generate_forward_exception();
5900 
5901     StubRoutines::_call_stub_entry =
5902       generate_call_stub(StubRoutines::_call_stub_return_address);



5903 
5904     // is referenced by megamorphic call
5905     StubRoutines::_catch_exception_entry = generate_catch_exception();
5906 
5907     // atomic calls
5908     StubRoutines::_atomic_xchg_entry          = generate_atomic_xchg();
5909     StubRoutines::_atomic_xchg_long_entry     = generate_atomic_xchg_long();
5910     StubRoutines::_atomic_cmpxchg_entry       = generate_atomic_cmpxchg();
5911     StubRoutines::_atomic_cmpxchg_byte_entry  = generate_atomic_cmpxchg_byte();
5912     StubRoutines::_atomic_cmpxchg_long_entry  = generate_atomic_cmpxchg_long();
5913     StubRoutines::_atomic_add_entry           = generate_atomic_add();
5914     StubRoutines::_atomic_add_long_entry      = generate_atomic_add_long();
5915     StubRoutines::_fence_entry                = generate_orderaccess_fence();
5916 
5917     // platform dependent
5918     StubRoutines::x86::_get_previous_fp_entry = generate_get_previous_fp();
5919     StubRoutines::x86::_get_previous_sp_entry = generate_get_previous_sp();
5920 
5921     StubRoutines::x86::_verify_mxcsr_entry    = generate_verify_mxcsr();
5922 


5967       }
5968       if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog)) {
5969         StubRoutines::_dlog = generate_libmLog();
5970       }
5971       if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog10)) {
5972         StubRoutines::_dlog10 = generate_libmLog10();
5973       }
5974       if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dpow)) {
5975         StubRoutines::_dpow = generate_libmPow();
5976       }
5977       if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin)) {
5978         StubRoutines::_dsin = generate_libmSin();
5979       }
5980       if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos)) {
5981         StubRoutines::_dcos = generate_libmCos();
5982       }
5983       if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtan)) {
5984         StubRoutines::_dtan = generate_libmTan();
5985       }
5986     }
5987 
5988     StubRoutines::_load_value_type_fields_in_regs = generate_return_value_stub(CAST_FROM_FN_PTR(address, SharedRuntime::load_value_type_fields_in_regs), "load_value_type_fields_in_regs", false);
5989     StubRoutines::_store_value_type_fields_to_buf = generate_return_value_stub(CAST_FROM_FN_PTR(address, SharedRuntime::store_value_type_fields_to_buf), "store_value_type_fields_to_buf", true);
5990   }
5991 
5992   void generate_all() {
5993     // Generates all stubs and initializes the entry points
5994 
5995     // These entry points require SharedInfo::stack0 to be set up in
5996     // non-core builds and need to be relocatable, so they each
5997     // fabricate a RuntimeStub internally.
5998     StubRoutines::_throw_AbstractMethodError_entry =
5999       generate_throw_exception("AbstractMethodError throw_exception",
6000                                CAST_FROM_FN_PTR(address,
6001                                                 SharedRuntime::
6002                                                 throw_AbstractMethodError));
6003 
6004     StubRoutines::_throw_IncompatibleClassChangeError_entry =
6005       generate_throw_exception("IncompatibleClassChangeError throw_exception",
6006                                CAST_FROM_FN_PTR(address,
6007                                                 SharedRuntime::
6008                                                 throw_IncompatibleClassChangeError));
6009 




 319     __ BIND(loop);
 320     __ movptr(rax, Address(c_rarg2, 0));// get parameter
 321     __ addptr(c_rarg2, wordSize);       // advance to next parameter
 322     __ decrementl(c_rarg1);             // decrement counter
 323     __ push(rax);                       // pass parameter
 324     __ jcc(Assembler::notZero, loop);
 325 
 326     // call Java function
 327     __ BIND(parameters_done);
 328     __ movptr(rbx, method);             // get Method*
 329     __ movptr(c_rarg1, entry_point);    // get entry_point
 330     __ mov(r13, rsp);                   // set sender sp
 331     BLOCK_COMMENT("call Java function");
 332     __ call(c_rarg1);
 333 
 334     BLOCK_COMMENT("call_stub_return_address:");
 335     return_address = __ pc();
 336 
 337     // store result depending on type (everything that is not
 338     // T_OBJECT, T_VALUETYPE, T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT)
 339     __ movptr(r13, result);
 340     Label is_long, is_float, is_double, is_value, exit;
 341     __ movl(rbx, result_type);
 342     __ cmpl(rbx, T_OBJECT);
 343     __ jcc(Assembler::equal, is_long);
 344     __ cmpl(rbx, T_VALUETYPE);
 345     __ jcc(Assembler::equal, is_value);
 346     __ cmpl(rbx, T_LONG);
 347     __ jcc(Assembler::equal, is_long);
 348     __ cmpl(rbx, T_FLOAT);


 349     __ jcc(Assembler::equal, is_float);
 350     __ cmpl(rbx, T_DOUBLE);
 351     __ jcc(Assembler::equal, is_double);
 352 
 353     // handle T_INT case
 354     __ movl(Address(r13, 0), rax);
 355 
 356     __ BIND(exit);
 357 
 358     // pop parameters
 359     __ lea(rsp, rsp_after_call);
 360 
 361 #ifdef ASSERT
 362     // verify that threads correspond
 363     {
 364      Label L1, L2, L3;
 365       __ cmpptr(r15_thread, thread);
 366       __ jcc(Assembler::equal, L1);
 367       __ stop("StubRoutines::call_stub: r15_thread is corrupted");
 368       __ bind(L1);
 369       __ get_thread(rbx);
 370       __ cmpptr(r15_thread, thread);
 371       __ jcc(Assembler::equal, L2);
 372       __ stop("StubRoutines::call_stub: r15_thread is modified by call");
 373       __ bind(L2);
 374       __ cmpptr(r15_thread, rbx);


 396     __ movptr(r13, r13_save);
 397     __ movptr(r12, r12_save);
 398     __ movptr(rbx, rbx_save);
 399 
 400 #ifdef _WIN64
 401     __ movptr(rdi, rdi_save);
 402     __ movptr(rsi, rsi_save);
 403 #else
 404     __ ldmxcsr(mxcsr_save);
 405 #endif
 406 
 407     // restore rsp
 408     __ addptr(rsp, -rsp_after_call_off * wordSize);
 409 
 410     // return
 411     __ vzeroupper();
 412     __ pop(rbp);
 413     __ ret(0);
 414 
 415     // handle return types different from T_INT
 416     __ BIND(is_value);
 417     if (ValueTypeReturnedAsFields) {
 418       // Handle value type returned as fields
 419       __ store_value_type_fields_to_buf(NULL);
 420       __ movptr(r13, result);
 421     }
 422     __ BIND(is_long);
 423     __ movq(Address(r13, 0), rax);
 424     __ jmp(exit);
 425 
 426     __ BIND(is_float);
 427     __ movflt(Address(r13, 0), xmm0);
 428     __ jmp(exit);
 429 
 430     __ BIND(is_double);
 431     __ movdbl(Address(r13, 0), xmm0);
 432     __ jmp(exit);
 433 
 434     return start;
 435   }
 436 
 437   // Return point for a Java call if there's an exception thrown in
 438   // Java code.  The exception is caught and transformed into a
 439   // pending exception stored in JavaThread that can be tested from
 440   // within the VM.
 441   //
 442   // Note: Usually the parameters are removed by the callee. In case
 443   // of an exception crossing an activation frame boundary, that is
 444   // not the case if the callee is compiled code => need to setup the
 445   // rsp.
 446   //
 447   // rax: exception oop
 448 
 449   address generate_catch_exception() {
 450     StubCodeMark mark(this, "StubRoutines", "catch_exception");
 451     address start = __ pc();


5887 
5888     RuntimeStub* stub = RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_in_words, oop_maps, false);
5889     return stub->entry_point();
5890   }
5891 
5892   // Initialization
5893   void generate_initial() {
5894     // Generates all stubs and initializes the entry points
5895 
5896     // This platform-specific settings are needed by generate_call_stub()
5897     create_control_words();
5898 
5899     // entry points that exist in all platforms Note: This is code
5900     // that could be shared among different platforms - however the
5901     // benefit seems to be smaller than the disadvantage of having a
5902     // much more complicated generator structure. See also comment in
5903     // stubRoutines.hpp.
5904 
5905     StubRoutines::_forward_exception_entry = generate_forward_exception();
5906 
5907     // Generate these first because they are called from other stubs
5908     StubRoutines::_load_value_type_fields_in_regs = generate_return_value_stub(CAST_FROM_FN_PTR(address, SharedRuntime::load_value_type_fields_in_regs), "load_value_type_fields_in_regs", false);
5909     StubRoutines::_store_value_type_fields_to_buf = generate_return_value_stub(CAST_FROM_FN_PTR(address, SharedRuntime::store_value_type_fields_to_buf), "store_value_type_fields_to_buf", true);
5910 
5911     StubRoutines::_call_stub_entry = generate_call_stub(StubRoutines::_call_stub_return_address);
5912 
5913     // is referenced by megamorphic call
5914     StubRoutines::_catch_exception_entry = generate_catch_exception();
5915 
5916     // atomic calls
5917     StubRoutines::_atomic_xchg_entry          = generate_atomic_xchg();
5918     StubRoutines::_atomic_xchg_long_entry     = generate_atomic_xchg_long();
5919     StubRoutines::_atomic_cmpxchg_entry       = generate_atomic_cmpxchg();
5920     StubRoutines::_atomic_cmpxchg_byte_entry  = generate_atomic_cmpxchg_byte();
5921     StubRoutines::_atomic_cmpxchg_long_entry  = generate_atomic_cmpxchg_long();
5922     StubRoutines::_atomic_add_entry           = generate_atomic_add();
5923     StubRoutines::_atomic_add_long_entry      = generate_atomic_add_long();
5924     StubRoutines::_fence_entry                = generate_orderaccess_fence();
5925 
5926     // platform dependent
5927     StubRoutines::x86::_get_previous_fp_entry = generate_get_previous_fp();
5928     StubRoutines::x86::_get_previous_sp_entry = generate_get_previous_sp();
5929 
5930     StubRoutines::x86::_verify_mxcsr_entry    = generate_verify_mxcsr();
5931 


5976       }
5977       if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog)) {
5978         StubRoutines::_dlog = generate_libmLog();
5979       }
5980       if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog10)) {
5981         StubRoutines::_dlog10 = generate_libmLog10();
5982       }
5983       if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dpow)) {
5984         StubRoutines::_dpow = generate_libmPow();
5985       }
5986       if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin)) {
5987         StubRoutines::_dsin = generate_libmSin();
5988       }
5989       if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos)) {
5990         StubRoutines::_dcos = generate_libmCos();
5991       }
5992       if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtan)) {
5993         StubRoutines::_dtan = generate_libmTan();
5994       }
5995     }



5996   }
5997 
5998   void generate_all() {
5999     // Generates all stubs and initializes the entry points
6000 
6001     // These entry points require SharedInfo::stack0 to be set up in
6002     // non-core builds and need to be relocatable, so they each
6003     // fabricate a RuntimeStub internally.
6004     StubRoutines::_throw_AbstractMethodError_entry =
6005       generate_throw_exception("AbstractMethodError throw_exception",
6006                                CAST_FROM_FN_PTR(address,
6007                                                 SharedRuntime::
6008                                                 throw_AbstractMethodError));
6009 
6010     StubRoutines::_throw_IncompatibleClassChangeError_entry =
6011       generate_throw_exception("IncompatibleClassChangeError throw_exception",
6012                                CAST_FROM_FN_PTR(address,
6013                                                 SharedRuntime::
6014                                                 throw_IncompatibleClassChangeError));
6015 


< prev index next >